由JVM处理`final` [英] Handling of `final` by the JVM

查看:370
本文介绍了由JVM处理`final`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在对此问题的评论中,我声称最终在某些情况下必须得到JVM的尊重。已经询问最终变量的安全出版物,因此处理静态最终成员。但是如何强制执行最终的类和方法并禁止覆盖最终字段呢?恕我直言,这可以而且必须在课程加载时完成。

In a comment to this question, 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. But what about enforcing classes and methods being final and forbidding overwriting of final fields? IMHO this can and must be done at class loading time.

我的论点是


  • 对于JVM的安全性至关重要,例如 String final ,因此不得加载扩展它的手工制作的类。

  • 同样适用于公共最终字段。虽然反射可以改变它们,但它会在运行时进行检查。因此,加载时必须拒绝重新分配最终字段的字节码。

  • For the security of the JVM is crucial that e.g. String is final, so a hand-crafted class extending it must not be loaded.
  • Similarly for public final fields. While reflection can change them, it's checked at runtime. Therefore a bytecode reassigning final fields must be rejected when loaded, too.

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

But I couldn't find a proof. Am I right?

推荐答案

是的,你说得对。

对于标记为 final 的类,请参阅 Java虚拟机规范:Java SE 8版,§ 4.10验证 class 文件,部分说明:

For classes marked as final, see The Java Virtual Machine Specification: Java SE 8 Edition, §4.10 "Verification of class Files", which says in part:


[…] the Java虚拟机需要自行验证它尝试合并的文件是否满足所需的约束。 Java虚拟机实现验证每个类文件是否满足链接时的必要约束(§5.4)。

[…] 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:


  • 确保 final 类没有子类。

  • […]

  • Ensuring that final classes are not subclassed.
  • […]

(有关更多详细信息,请参阅此处,包括当 class 文件违反此约束时JVM应执行的操作。)

(See there for many more details, including what the JVM is supposed to do when a class file violates this constraint.)

对于标记为 final 的字段,请参阅同上,§§ 6.5– 6 putfield putstatic ,其中部分代表 putfield

For fields marked as final, see ibid., §§6.5–6 "putfield" and "putstatic", which say in part of putfield:


否则,如果字段为 final ,则必须在当前类,指令必须在实例初始化m中发生当前类的ethod(< init> )。否则,抛出 IllegalAccessError

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 ,但使用< clinit> 方法而不是实例初始化方法(< init> )。

and likewise of putstatic, but with "the <clinit> method" instead of "an instance initialization method (<init>).

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

(As you may have guessed, putfield and putstatic are the bytecode instructions for setting instance and static fields, respectively.)

这篇关于由JVM处理`final`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆