gpt4 book ai didi

Java final 方法使用静态绑定(bind),但 JVM 在编译时使用 "invokevirtual"指令

转载 作者:行者123 更新时间:2023-11-30 07:55:42 26 4
gpt4 key购买 nike

很多书上说java final实例方法(非私有(private))使用静态绑定(bind),其他实例方法(非私有(private))使用动态绑定(bind)。但是在编译时,它们都使用“invokevirtual”JVM 指令。 JVM执行“invokevirtual”指令时是否区分final方法和非final方法?我最初认为final方法使用“invokespecial”作为私有(private)实例方法,因为它们都使用静态绑定(bind)。

最佳答案

编译后的形式是JLS §13.4.17的直接结果在第 13 章“二进制兼容性”中:

13.4.17. final Methods

Changing a method that is declared final to no longer be declared final does not break compatibility with pre-existing binaries.

这意味着调用者的形式不应该反射(reflect)目标方法在编译时是否是final(或者当有不同的表示时,不允许产生实际差异在运行时)。

为了与其他形式的调用进行比较,在不破坏与调用者的兼容性的情况下移除static修饰符是不可能的,因此,使用专用的对调用形式进行编码是一致的invokestatic 指令。

对于 private 方法的调用,调用者必须在同一个类中,因此,在添加或删除 private 修饰符时会重新编译(仅考虑有效的调用者) ,因此在同一类中调用 private 方法时使用 invokespecial 没有问题。从 JDK 11 开始,private 方法可能会被属于同一嵌套组的其他类中的调用者调用;在那种情况下,其他类中的这些调用者不使用 invokespecial

所以 final 和非 final 方法之间的区别确实发生在运行时,当 JVM 知道实际的目标方法时,if这种区别根本不会发生。符合规范的 JVM 必须拒绝试图重写 final 方法的类,但它们不需要执行有关调用的优化。实际上,今天的 JVM 能够优化所有未被重写的方法的调用,无论此属性是否已由 final 修饰符强制执行。唯一的区别是,将新类加载到 JVM 中并覆盖非 final 方法可能会导致调用者去优化。

关于Java final 方法使用静态绑定(bind),但 JVM 在编译时使用 "invokevirtual"指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42991664/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com