JVM 处理 `final`
Handling of `final` by the JVM
对此 , I'm claiming that final
in some cases must be honored by the JVM. The safe publication of final
variables has been already asked and so was the handling of static final members 的评论。但是强制 classes 和方法是 final 并禁止覆盖 final 字段呢?恕我直言,这可以而且必须在 class 加载时间完成。
我的观点是
- JVM 的安全性至关重要,例如
String
是 final
,因此不得加载手工制作的 class 扩展它。
- 与
public final
字段类似。虽然反射可以改变它们,但它是在运行时检查的。因此,重新分配最终字段的字节码在加载时也必须被拒绝。
但我找不到证据。我说的对吗?
是的,你是对的。
对于标记为 final
的 类,请参阅 The Java Virtual Machine Specification: Java SE 8 Edition, §4.10 "Verification of class
Files",其中部分内容为:
[…] the Java Virtual Machine needs to verify for itself that the desired constraints are satisfied by the class
files it attempts to incorporate. A Java Virtual Machine implementation verifies that each class file satisfies the necessary constraints at linking time (§5.4).
[…]
[…] there are three additional checks outside the Code
attribute which must be performed during verification:
- Ensuring that
final
classes are not subclassed.
- […]
(请参阅此处了解更多详细信息,包括当 class
文件违反此约束时 JVM 应该执行的操作。)
对于标记为 final
的字段,请参阅 ibid., §§6.5–6 "putfield
" and "putstatic
",其中在 putfield
的一部分中表示:
Otherwise, if the field is final
, it must be declared in the current class, and the instruction must occur in an instance initialization method (<init>
) of the current class. Otherwise, an IllegalAccessError
is thrown.
和 putstatic
一样,但使用 "the <clinit>
method" 而不是“实例初始化方法 (<init>
).
(你可能已经猜到了,putfield
和putstatic
分别是设置实例和静态字段的字节码指令。)
对此 final
in some cases must be honored by the JVM. The safe publication of final
variables has been already asked and so was the handling of static final members 的评论。但是强制 classes 和方法是 final 并禁止覆盖 final 字段呢?恕我直言,这可以而且必须在 class 加载时间完成。
我的观点是
- JVM 的安全性至关重要,例如
String
是final
,因此不得加载手工制作的 class 扩展它。 - 与
public final
字段类似。虽然反射可以改变它们,但它是在运行时检查的。因此,重新分配最终字段的字节码在加载时也必须被拒绝。
但我找不到证据。我说的对吗?
是的,你是对的。
对于标记为 final
的 类,请参阅 The Java Virtual Machine Specification: Java SE 8 Edition, §4.10 "Verification of class
Files",其中部分内容为:
[…] the Java Virtual Machine needs to verify for itself that the desired constraints are satisfied by the
class
files it attempts to incorporate. A Java Virtual Machine implementation verifies that each class file satisfies the necessary constraints at linking time (§5.4).[…]
[…] there are three additional checks outside the
Code
attribute which must be performed during verification:
- Ensuring that
final
classes are not subclassed.- […]
(请参阅此处了解更多详细信息,包括当 class
文件违反此约束时 JVM 应该执行的操作。)
对于标记为 final
的字段,请参阅 ibid., §§6.5–6 "putfield
" and "putstatic
",其中在 putfield
的一部分中表示:
Otherwise, if the field is
final
, it must be declared in the current class, and the instruction must occur in an instance initialization method (<init>
) of the current class. Otherwise, anIllegalAccessError
is thrown.
和 putstatic
一样,但使用 "the <clinit>
method" 而不是“实例初始化方法 (<init>
).
(你可能已经猜到了,putfield
和putstatic
分别是设置实例和静态字段的字节码指令。)