当调用虚拟存在时,为什么需要调用Special
有三个操作码可以调用 Java 方法。很明显,invokeStatic 仅用于静态方法调用。
据我所知,在调用构造函数和私有方法时使用 invokespecial。那么,我们是否需要在运行时区分私有和公共方法调用呢?它可以用相同的操作码调用,比如调用虚拟?
JVM 是否处理私有和公共方法定义?据我所知,公共和私有关键字只是在开发阶段需要封装吗?
有三个操作码可以调用 Java 方法。很明显,invokeStatic 仅用于静态方法调用。
据我所知,在调用构造函数和私有方法时使用 invokespecial。那么,我们是否需要在运行时区分私有和公共方法调用呢?它可以用相同的操作码调用,比如调用虚拟?
JVM 是否处理私有和公共方法定义?据我所知,公共和私有关键字只是在开发阶段需要封装吗?
从这个网站
如果仔细阅读 Java VM 规范,可以很容易地找到答案:
invokespecial 和 invokevirtual 指令之间的区别在于 invokevirtual 基于对象的类调用方法。invokespecial 指令用于调用实例初始化方法以及私有方法和当前类的超类的方法。
换句话说,invokespecial 用于调用方法而不考虑动态绑定,以便调用特定类的方法版本。
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() 版本。