从内部类到外部接口的非静态访问的基本障碍

时间:2014-01-28 23:02:12

标签: java static java-8

示例:

interface Outer {
    default String get() {
        return "hi";
    }
    class Inner {
        String got() {
            return get();
        }
    }
}

这会产生错误

  

java:非静态方法get()不能从静态上下文中引用。

内部接口/类始终是静态的;与外部类不同,除非声明为静态,否则它是非静态的。

这就是今天和即将发布的Java 8中的事情。外部类和外部接口之间存在这种差异的根本原因是什么?

更新: 在阅读@ Radiodef的评论之后,我将内部接口更改为内部类。外部类不能包含非静态内部接口,因此该示例令人困惑。无论如何,内心阶层真的是我想要的。

更新:供参考。这完全合法:

class Outer {
    String get() {
        return "hei";
    }
    class Inner {
        String got() {
            return get();
        }
    }
}

2 个答案:

答案 0 :(得分:9)

也许我误解了您的问题,但您的代码段完全等同于

interface Outer {
    public default String get() {
        return "hi";
    }
    public static class Inner {
        String got() {
            return get();
        }
    }
}

作为the JLS Chapter 9.5 (Java 8)

  

接口中的成员类型声明是隐式public和   static。允许冗余地指定其中一个或两个   改性剂。

所以如果你做了

Inner innerInstance = new Outer.Inner();
innerInstance.got();

get()调用什么?此处不涉及Outer类型的对象。

  

外在之间是否存在这种差异的根本原因   类和外部接口?

这不是问题。 您的班级代码是inner classes 的示例,即。非static嵌套类。 接口代码是static嵌套类的示例。你正在比较两种不同的东西。

封闭类中具有static嵌套类的等效示例将是

class Outer {
    String get() {
        return "hei";
    }

    public static class Inner {
        String got() {
            return get(); // won't compile
        }
    }
}

同样,get()无法正常工作,因为没有相应的(封闭的)实例可以调用它。


@Radiodef所提出的问题是

  

为什么这个类必须是隐式静态的,除此之外   现有规格?

然后我的答案如下:

根据定义,界面是

  

独立系统或不同群体互动的点

接口没有状态,也没有行为。它只是描述行为。接口成员隐式static,因为接口没有状态。另一方面,接口类型具有状态是有意义的,即。 static个成员。重要的是它是一个引用类型,而不是它是一个接口。

答案 1 :(得分:0)

我将为您提供一种记住它的方式。

  1. 对于static成员,它没有绑定到声明的类/接口的对象;对于非static成员,它必须绑定到声明类的对象。
  2. static外,所有接口的成员都是隐式default

因此,在您的示例中:static class Inner未绑定到interface Outer的对象(由于{em {em}} 的对象没有意义),因此它无法调用interface的成员。

对于更新中的合法用户:Outer绑定到class Inner的对象,因此,当您创建class Outer的对象时,创建Inner的匿名对象,因此在class Outer中调用get()时,将在该匿名对象上调用Inner::got()

希望获得帮助。