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 加载时间完成。

我的观点是

但我找不到证据。我说的对吗?

是的,你是对的。


对于标记为 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>).

(你可能已经猜到了,putfieldputstatic分别是设置实例和静态字段的字节码指令。)