首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java最终方法使用静态绑定,但JVM在编译时使用"invokevirtual“指令

Java最终方法使用静态绑定,但JVM在编译时使用"invokevirtual“指令
EN

Stack Overflow用户
提问于 2017-03-24 12:53:28
回答 2查看 282关注 0票数 2

很多书都说java的最终实例方法(不是私有的)使用静态绑定,而其他实例方法(不是私有的)使用动态绑定。但是,在编译时,它们都使用"invokevirtual“JVM指令。当JVM执行"invokevirtual“指令时,最终方法和非最终方法有区别吗?我最初认为final方法使用"invokespecial“作为私有实例方法,因为它们都使用静态绑定。

EN

回答 2

Stack Overflow用户

发布于 2019-03-21 21:08:13

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

13.4.17。final方法

将声明为final的方法更改为不再声明为final不会破坏与预先存在的二进制文件的兼容性。

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

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

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

因此,final和非final方法之间的区别确实发生在运行时,当JVM知道实际的目标方法时,如果有这种区别的话。符合要求的JVM必须拒绝试图覆盖final方法的类,但它们不需要执行关于调用的优化。在实践中,今天的JVM能够优化所有未被覆盖的方法的调用,而不管此属性是否已由final修饰符强制执行。惟一的区别是,将覆盖非final方法的新类加载到JVM中可能会导致调用方的反优化。

票数 3
EN

Stack Overflow用户

发布于 2017-03-24 13:15:11

除了invokevirtual之外,没有其他字节码指令可以调用由类声明的实例方法。它的名字令人困惑。它也可以命名为invokeClassMethodinvokeclass。实际上,编译器并不特别对待final方法。invokespecial用于调用构造函数和静态初始值设定项。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42991664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档