首先我想问Why does Java prohibit static fields in inner classes?,但问题已经存在了。 Bozho的回答消除了我给他们需要的原因(serialVersionUID
)。但是,我仍然很好奇:
是否仅在源代码或类文件中禁止静态字段?
是的,一个令人信服的理由,为什么禁止这种行为还有待发明。在C中,即使在函数内部也允许使用静态变量。它们的寿命与任何其他静态变量相同,只是它们的可见性不同。同样适用于Java。答案 0 :(得分:5)
内部类可以定义静态字段:
内部类可能不会声明静态成员,除非它们是编译时常量字段(第15.28节)。
因此,您可以定义序列版本ID。
当静态字段不是常量时,则逻辑不被允许 - 静态字段不需要类的实例 - 它们是每个类,而内部类需要拥有类的实例 - 它们不能存在一个实例。虽然它可能是静态字段是内部类被定义为好像它们在拥有类中,但它会更加混乱。
答案 1 :(得分:3)
如果设计允许静态内容,那么会发生什么不好的事情。在类文件级别没有问题,我认为,字节代码没有内部类的概念。
但这会令人困惑:
class X
class Y
static int z;
X x1 = new X();
X.Y y1 = x1.new Y();
X x2 = new X();
X.Y y2 = x2.new Y();
X.Y y3 = x2.new Y();
直观地,y2
和y3
应该共享相同的z
,但它应该与z
看到的y1
相同吗?
从概念上讲,内部类仅在外部实例中有效。甚至可以想象,当外部实例是GC时,JVM会将其卸载; [1]中针对类卸载给出的参数不适用,因为内部类没有静态变量或静态初始化器。
然而现实是,无论外部实例如何,所有内部实例都共享一个类。这当然是正确的:y1.getClass()==y2.getClass()==y3.getClass()
。
可以说,语言规范规定它是真的:[2]
两个引用类型是相同的运行时类型,如果...由同一个类加载器定义,并且具有相同的二进制名称
y1的类和y2的类具有相同的类加载器,X.Y的二进制名称定义良好且独立于外部实例。所以y1和y2必须具有相同的运行时类。
如果语言规范实际上暗示内部类独立于外部实例,则内部类中对静态状态的普遍接受的解释被削弱。
[1] http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7
[2] http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.4
答案 2 :(得分:1)
静态成员不允许仅在非静态内部类的情况下,bcz非静态内部类也充当外部类的方法,因此所有方法规则都适用于内部类。我们可以在静态内部声明静态成员类.....
基本规则