当前位置: 首页 > 知识库问答 >
问题:

Java final方法使用静态绑定,而JVM在编译时使用“invokevirtual”指令

康弘义
2023-03-14

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

共有1个答案

宋鸿德
2023-03-14

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

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

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

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

 类似资料:
  • 我在想什么时候使用静态方法?假设我有一个类有几个getter和setter,一两个方法,并且我希望这些方法只能在类的实例对象上调用。这是否意味着我应该使用静态方法? 示例: ...或: 我很困惑!

  • 本文向大家介绍go语言静态库的编译和使用方法,包括了go语言静态库的编译和使用方法的使用技巧和注意事项,需要的朋友参考一下 本文主要介绍go语言静态库的编译和使用方法,以windows平台为例,linux平台步骤一样,具体环境如下: 在%GOPATH%\src目录,有demo包和使用demo包的应用程序main.go,main.go代码如下: demo包中的demo.go代码如下: 由于demo.

  • 问题内容: 我想知道何时使用静态方法?假设我有一个带有几个和的类,一个或两个方法,并且我希望这些方法只能在该类的实例对象上调用。这是否意味着我应该使用静态方法? 例如 要么 我很困惑! 问题答案: 一个经验法则:问自己“即使尚未构建Obj,调用此方法是否有意义?” 如果是这样,那肯定是静态的。 因此,在一个类中,Car你可能有一个静态的方法,因为即使没有人制造过汽车,也可能想知道35mpg转换为什

  • 问题内容: 我想知道何时使用静态方法?假设我有一个带有几个getter和setter的类,一个或两个方法,并且我希望这些方法只能在该类的实例对象上调用。这是否意味着我应该使用静态方法? 例如 要么 (这是静态方式吗?) 我很困惑! 问题答案: 一个经验法则:问自己“即使尚未构建Obj,调用此方法是否有意义?” 如果是这样,那肯定是静态的。 因此,在一个类中,你可能有一个静态的方法,因为即使没有人制

  • 本文向大家介绍Linux下g++编译与使用静态库和动态库的方法,包括了Linux下g++编译与使用静态库和动态库的方法的使用技巧和注意事项,需要的朋友参考一下 在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库(*.a)与动态库(*.so)的生成与使

  • 问题内容: 在我提出问题之前,让我解释一下我的理解和看法。 除非进行覆盖,否则仅通过Override才能实现多态。而且,它只能在运行时看到,人们可能将其命名为“运行时多态性”。( 我不反对将 多态 称为 运行时多态 ) 我反对 将 方法重载 称为 编译时多态 或多 态 。 我同意 方法重载 是静态绑定(编译时绑定),但是我看不到其中的多态性。 根据javadoc,只有多态性。没有编译时或运行时多态