嵌套在类中的接口可以是非静态的吗?

时间:2019-04-12 11:12:29

标签: java

我正在在线阅读有关Java中的嵌套接口的一些文章[1] [2],我明白这一点

PKs

但我不确定

interface A {
    ...
    interface B { // this is static by default
        ...
    }
}

简而言之,“嵌套接口始终是静态的”是真的吗?

[1] https://beginnersbook.com/2016/03/nested-or-inner-interfaces-in-java/
[2] https://www.programcreek.com/2013/08/inner-interface-in-java/

3 个答案:

答案 0 :(得分:3)

是的,您的“简而言之”总是正确的。直接从language spec报价:

  

成员接口是隐式静态的(第9.1.1节)。允许成员接口的声明冗余地指定“静态”修饰符。

其中定义了“成员接口”的shortly before

  

成员接口是其声明直接包含在另一个类或接口声明的主体中的接口(第8.1.6节,第9.1.4节)。

答案 1 :(得分:2)

一个非静态内部类只是语法糖。非静态内部类与标准“外部”类完全相同,但有一个例外:它具有外部类类型的不可见字段,并声明为final。内部类的所有构造函数都必须将必须设置该字段的外部实例作为第一个参数。.然后,遍历所有语法糖袋以隐藏它们。

但这确实是它的工作方式,您可以使用javap进行确认。因此,鉴于:

public class Outer { public class Inner {} }

与之相对:

public class Outer {}
class Desugared {
    private final Outer outer;
    public Desugared(Outer outer) { this.outer = outer; }
}

除了语法外,这些都是一样的

Outer o = new Outer();
o.new Outer.Inner();

与以下相同:

Outer o = new Outer();
new Desugared(o);

等。

这就是问题:接口没有字段

鉴于他们没有,他们无法拥有此隐藏字段。因此,它们不能是“非静态的”。因此,它们是隐式的“静态”(它们没有隐式可用的外部类实例),并且您不能更改它。

答案 2 :(得分:1)

可能会实例化类 ,而可能会不能实例化接口。

含义:当您具有内部时,您可能会或可能不希望使用“外部”对象创建该内部类的实例。

假设您拥有:

class X {
  ... class Y { 

然后someInstanceOfX.new Y()new X.Y()可能都有意义。

但是,当您有内部接口时,使用该接口将与其他一些implements C.D类一起使用。没有任何有意义的方法可以访问C.D,这表明D不应为静态。

就像您的第二个链接所说的那样:

  

因为不能实例化接口,所以仅当内部接口是静态的时,内部接口才有意义。