当调用虚拟存在时,为什么需要调用Special

2022-08-31 16:42:13

有三个操作码可以调用 Java 方法。很明显,invokeStatic 仅用于静态方法调用。

据我所知,在调用构造函数和私有方法时使用 invokespecial。那么,我们是否需要在运行时区分私有和公共方法调用呢?它可以用相同的操作码调用,比如调用虚拟?

JVM 是否处理私有和公共方法定义?据我所知,公共和私有关键字只是在开发阶段需要封装吗?


答案 1

这个网站

如果仔细阅读 Java VM 规范,可以很容易地找到答案:

invokespecial 和 invokevirtual 指令之间的区别在于 invokevirtual 基于对象的类调用方法。invokespecial 指令用于调用实例初始化方法以及私有方法和当前类的超类的方法。

换句话说,invokespecial 用于调用方法而不考虑动态绑定,以便调用特定类的方法版本。


答案 2

http://www.artima.com/underthehood/invocationP.html上面的链接清楚地给出了有价值的例子,这些例子增加了我的问题。

class Superclass {

    private void interestingMethod() {
        System.out.println("Superclass's interesting method.");
    }

    void exampleMethod() {
        interestingMethod();
    }
}

class Subclass extends Superclass {

    void interestingMethod() {
        System.out.println("Subclass's interesting method.");
    }

    public static void main(String args[]) {
        Subclass me = new Subclass();
        me.exampleMethod();
    }
}

当您在子类中调用 main() 时,如上定义,它必须打印“超类的有趣方法”。如果使用 invokevirtual,它将打印“子类的有趣方法”。为什么?因为虚拟机会根据对象的实际类(即子类)选择要调用的有趣Method()。因此,它将使用子类的有趣Method()。另一方面,使用 invokespecial,虚拟机将根据引用的类型选择方法,因此将调用 Superclass 的 interestingMethod() 版本。


推荐