java当invokeVirtual存在时为什么需要invokeSpecial
有三个操作码可以调用Java方法。显然,invokeStatic只是用于静态方法调用
据我所知,调用构造函数和私有方法时使用invokespecial。那么,我们需要在运行时区分私有和公共方法调用吗?它可以用相同的操作码调用,比如invokevirtual
JVM是否处理私有和公共方法定义?据我所知,在开发阶段封装只需要公共和私有关键字
你可以在下面搜索框中键入要查询的问题!
有三个操作码可以调用Java方法。显然,invokeStatic只是用于静态方法调用
据我所知,调用构造函数和私有方法时使用invokespecial。那么,我们需要在运行时区分私有和公共方法调用吗?它可以用相同的操作码调用,比如invokevirtual
JVM是否处理私有和公共方法定义?据我所知,在开发阶段封装只需要公共和私有关键字
# 1 楼答案
感谢您阅读该解释:如果它有助于您在方法调用期间识别汇编指令的创建,请不要忘记向上投票 这里我将解释静态绑定和动态绑定
首先,我要告诉大家,invokeStatic、invokeSpecial、invokeVirtual、invokeInterface等是编译器在编译过程后生成的汇编指令。 我们都知道我们有一个。编译后的类文件格式,我们无法读取它。但是java提供了一个名为“javap”的工具
我们可以读出我们的名字。使用javap命令对文件汇编指令进行分类。默认情况下,我们看不到私有方法汇编指令,所以我们需要使用-private。以下是查看java编译器生成的汇编指令的命令:
假设你有一个.java类
甲级 { public void printValue() { 系统出来println(“A内部”); }
公共静态无效调用方法(A) { a、 printValue(); } }
打开cmd prompt并转到包含java文件A.java的文件夹
运行javac A.java
现在生成了一个.class文件,其中包含汇编指令,但您无法读取它
现在运行javap-ca
您可以看到方法调用的程序集生成>a.printValue()
如果printValue()方法是私有的,则需要使用javap-c-private A
您可以将printValue()设置为private/static/public/private static
还有一件事需要记住,第一个编译器检查调用方法的对象。然后找到它的类类型,并在该类中找到该方法(如果可用或不可用)
注意:现在请记住,如果调用方法是静态的,则会生成invokeStatic汇编;如果调用方法是私有的,则会生成invokeSpecial汇编指令;如果调用方法是公共的,则会生成invokeVirtual指令。公共方法并不意味着每次生成invokeVirtual指令时。以防超级。来自A的子类的printValue()调用是例外情况。i、 e.如果A是B的父类,B包含相同的方法printValue(),那么它将生成invokeVirtual(动态),但如果B中的printValue()具有super。printValue()作为其第一条语句,然后生成invokeStatic,即使A的printValue()是公共的
我们也来试试这个:
>;通过测试保存它。JAVA >;运行javac测试。JAVA >;javap-c-私有测试
# 2 楼答案
从this site
# 3 楼答案
http://www.artima.com/underthehood/invocationP.html 上面的链接提供了一些有价值的例子,可以清楚地回答我的问题
当您在上面定义的子类中调用main()时,它必须打印“超类的有趣方法”如果使用invokevirtual,它将打印“子类有趣的方法”为什么?因为虚拟机会根据对象的实际类(即子类)选择要调用的interestingMethod()。所以它将使用子类的interestingMethod()。另一方面,使用invokespecial,虚拟机将根据引用的类型选择方法,因此将调用超类版本的interestingMethod()