maa*_*nus 4 java static-members inner-classes
首先我想问为什么Java禁止内部类中的静态字段?,但问题已经出现了.serialVersionUIDBozho的回答消除了我给予他们()的原因.但是,我仍然很好奇:
静态字段是仅在源代码中还是在类文件中禁止?
顺便说一句,这是一个令人信服的理由,为什么禁止这种行为还有待发明.在C中,即使在函数内部也允许使用静态变量.它们的寿命与任何其他静态变量相同,只是它们的可见性不同.同样适用于Java.
内部类可以定义静态字段:
内部类可能不会声明静态成员,除非它们是编译时常量字段(第15.28节).
因此,您可以定义序列版本ID.
当静态字段不是常量时,则不允许逻辑 - 静态字段不需要类的实例 - 它们是每个类,而内部类需要拥有类的实例 - 它们在没有实例的情况下不能存在.虽然可能是静态字段是内部类被定义为好像它们在拥有类中,但它会更加混乱.
如果它们被设计为允许静态的东西,那么就不会发生真正糟糕的事情。在类文件级别没有问题,我认为字节码没有内部类的概念。
但这会令人困惑:
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();
Run Code Online (Sandbox Code Playgroud)
直观上看,y2和y3应该是相同的,但是所看到的z应该是相同的吗?zy1
从概念上讲,内部类仅在外部实例中有效。甚至可以想象,当外部实例被 GC 时,JVM 会卸载它;[1] 中给出的反对类卸载的参数不适用,因为内部类没有静态变量或静态初始值设定项。
然而现实是,无论外部实例如何,所有内部实例都共享一个类。这当然是真的:y1.getClass()==y2.getClass()==y3.getClass()。
可以说语言规范表明它是正确的:[2]
两个引用类型是相同的运行时类型 if ... 由相同的类加载器定义,并且具有相同的二进制名称
y1 的类和 y2 的类具有相同的类加载器,XY 的二进制名称定义明确且独立于外部实例。因此 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
| 归档时间: |
|
| 查看次数: |
6842 次 |
| 最近记录: |