《Java虚拟机学习》JVM虚拟机是如何执行方法

1. 重载与重写方法

重载

重载 :同一个类中,方法名相同,形参列表不用,与返回值无关

对于重载方法的执行,JVM遵循下面的三条规则:

  1. 在不考虑对基本类型自动装拆箱(auto-boxing,auto-unboxing),以及可变长参数的情况下选取重载方法;

  2. 如果在第 1 个阶段中没有找到适配的方法,那么在允许自动装拆箱,但不允许可变长参数的情况下选取重载方法;

  3. 如果在第 2 个阶段中没有找到适配的方法,那么在允许自动装拆箱以及可变长参数的情况下选取重载方法。

package jike.test;

public class JVMInvokeMethodDemo {


    class Test{

        //方法1 基本类型自动装拆箱  以及 可变参
        public void method(Integer arg1,String... arg2){

            System.out.println("方法一执行");

        }

        //方法2 基本类型自动装拆箱
        public void method(Integer arg1,String arg2){

            System.out.println("方法二执行");

        }

        //方法3 基本类型自动装拆箱
        public void method(int arg1,String arg2){

            System.out.println("方法三执行");

        }

    }

    public static void main(String[] args) {

        JVMInvokeMethodDemo jvmInvokeMethodDemo = new JVMInvokeMethodDemo();

        Test test = jvmInvokeMethodDemo.new Test();

        test.method(1,"执行");

    }


}

idea64_Hr1V2luUeD

如上面的代码所示,首先会执行方法三;当方法三屏蔽时,会根据规则二,找自动装拆箱的方法二;只有当方法二也屏蔽时,JVM才会去执行自动装拆箱以及可变参的方法一。

重写

重写: 子类重写父类的方法,遵循两大一小两相同的原则。即返回值类型与权限修饰符大于或等于父类,抛出异常小于等于父类,形参列表与方法名跟父类相同

对于重写方法,JVM会根据调用者的动态类型,来选择实际的目标方法

2. JVM识别方法的方式

JVM区别方法主要通过 类名,方法名,方法描述符(形参列表+返回值组成)

但对于JAVA而言,返回值不能用于区别方法,如下所示,IDEA就会给出错误提示,但对于JVM而言,

并不存在问题。因为对于JVM来说,调用方法的字节码包含了返回值信息,JVM能够准确定位到目标方法;

image-20230507173344885

为什么JAVA不能根据返回值区分呢? 因为一个方法的返回值可以选择是否接收。如下所示,没有明确表示返回值的类型,JVM是无法定位到具体方法的。

image-20230507173835727

3.静态绑定与动态绑定

重载基于JAVA的多态性来说是编译时多态,而重写是运行时多态。因此:

重载视为静态绑定,在编译时已经确定了目标方法;而重写则是动态绑定。但有一种情况就比较特殊: 子类重写了父类的重载方法,那么JVM就不能静态绑定了,还是需要在运行时根据调用者的动态类型来识别目标方法。

4. 调用方法的字节码命令

  1. invokestatic:用于调用静态方法。
  2. invokespecial:用于调用私有实例方法、构造器,以及使用 super 关键字调用父类的实例方法或构造器,和所实现接口的默认方法。
  3. invokevirtual:用于调用非私有实例方法。
  4. invokeinterface:用于调用接口方法。
  5. invokedynamic:用于调用动态方法。

5.符号引用如何找到具体引用

对于非接口符号引用,假定该符号引用所指向的类为 C,则 Java 虚拟机会按照如下步骤进行查找。

  1. 在 C 中查找符合名字及描述符的方法。
  2. 如果没有找到,在 C 的父类中继续搜索,直至 Object 类。
  3. 如果没有找到,在 C 所直接实现或间接实现的接口中搜索,这一步搜索得到的目标方法必须是非私有、非静态的。并且,如果目标方法在间接实现的接口中,则需满足 C 与该接口之间没有其他符合条件的目标方法。如果有多个符合条件的目标方法,则任意返回其中一个。

对于接口符号引用,假定该符号引用所指向的接口为 I,则 Java 虚拟机会按照如下步骤进行查找。

  1. 在 I 中查找符合名字及描述符的方法。如果没有找到,在 Object 类中的公有实例方法中搜索。
  2. 如果没有找到,则在 I 的超接口中搜索。这一步的搜索结果的要求与非接口符号引用步骤 3 的要求一致。

猜你喜欢

转载自blog.csdn.net/JAVAlife2021/article/details/130547314