Rah*_*arg 140 java static class inner-classes
为什么我们不能在非静态内部类中使用静态方法?
如果我使内部类静态,它的工作原理.为什么?
Bil*_*ard 108
因为内部类的实例与其外部类的实例隐式关联,所以它本身不能定义任何静态方法.由于静态嵌套类不能直接引用其封闭类中定义的实例变量或方法,因此它只能通过对象引用来使用它们,在静态嵌套类中声明静态方法是安全的.
Edd*_*die 45
在非静态内部类中允许静态方法没有多大意义; 你怎么去访问它?您无法访问(至少最初)非静态内部类实例而无需通过外部类实例.创建非静态内部类没有纯粹的静态方法.
对于外部类Outer,您可以访问如下静态方法test():
Outer.test();
Run Code Online (Sandbox Code Playgroud)
对于静态内部类Inner,您可以innerTest()像这样访问其静态方法:
Outer.Inner.innerTest();
Run Code Online (Sandbox Code Playgroud)
但是,如果Inner不是静态的,那么现在没有纯粹的静态方法来引用该方法innertest.非静态内部类与其外部类的特定实例相关联.函数与常量不同,Outer.Inner.CONSTANT因为对函数调用Outer.Inner.staticFunction();不保证引用是明确的.假设您有Inner.staticFunction()那些getState()定义的调用Outer.如果您尝试调用该静态函数,则现在对Inner类有一个不明确的引用.也就是说,你在内部类的哪个实例上调用静态函数?这很重要.看,由于对外部对象的隐式引用,没有真正的静态方法来引用该静态方法.
保罗贝洛拉是正确的,语言设计师可以允许这样做.然后,他们必须小心地禁止对非静态内部类的静态方法中对外部类的隐式引用的任何访问.在这一点上,如果你不能引用外部类,除了静态之外,这是一个内部类的值是什么?如果静态访问没问题,为什么不将整个内部类声明为静态呢?如果你只是让内部类本身是静态的,那么你没有对外部类的隐式引用,并且你不再有这种歧义.
如果您确实需要非静态内部类的静态方法,那么您可能需要重新考虑您的设计.
gus*_*afc 20
我有一个理论,可能是也可能不正确.
首先,您应该了解一些关于如何在Java中实现内部类的事情.假设你有这门课:
class Outer {
private int foo = 0;
class Inner implements Runnable {
public void run(){ foo++; }
}
public Runnable newFooIncrementer(){ return new Inner(); }
}
Run Code Online (Sandbox Code Playgroud)
编译它时,生成的字节码看起来就像你写了这样的东西:
class Outer {
private int foo = 0;
static class Inner implements Runnable {
private final Outer this$0;
public Inner(Outer outer){
this$0 = outer;
}
public void run(){ this$0.foo++; }
}
public Runnable newFooIncrementer(){ return new Inner(this); }
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们在非静态内部类中允许静态方法,您可能希望执行类似这样的操作.
class Outer {
private int foo = 0;
class Inner {
public static void incrFoo(){ foo++; }
}
}
Run Code Online (Sandbox Code Playgroud)
......看起来相当合理,因为这个Inner类似乎每个Outer实例都有一个化身.但正如我们上面所看到的,非静态内部类实际上只是静态"内部"类的语法糖,所以最后一个例子大致相当于:
class Outer {
private int foo = 0;
static class Inner {
private final Outer this$0;
public Inner(Outer outer){
this$0 = outer;
}
public static void incrFoo(){ this$0.foo++; }
}
}
Run Code Online (Sandbox Code Playgroud)
......这显然this$0是行不通的,因为它是非静态的.这种解释了为什么不允许使用静态方法(尽管你可以使参数允许静态方法,只要它们不引用封闭对象),以及为什么你不能有非最终静态字段(如果来自不同对象的非静态内部类的实例共享"静态",那将是违反直觉的.这也解释了为什么最终场被允许的(只要他们不引用封闭的对象).
唯一的原因是"不是必须",为什么还要费心去支持呢?
从语法上讲,没有理由禁止内部类具有静态成员.虽然一个实例Inner与一个实例关联Outer,但是如果java决定这样做,它仍然可以Outer.Inner.myStatic用来引用一个静态成员Inner.
如果您需要在所有实例之间共享某些内容Inner,您可以将它们Outer作为静态成员放入.这并不比使用静态成员更糟糕Inner,其中Outer仍然可以访问任何私有成员Inner(不会改进封装).
如果您需要Inner在由一个outer对象创建的所有实例之间共享某些内容,那么将它们Outer作为普通成员放入类中会更有意义.
我不同意"静态嵌套类几乎只是顶级类"的观点.我认为将静态嵌套类/内部类视为外部类的一部分更好,因为它们可以访问外部类的私有成员.外族的成员也是"内在阶级的成员".因此,不需要在内部类中支持静态成员.外部类中的普通/静态成员就足够了.