Home  >  Article  >  Java  >  How to use the Java JVM method dispatch model

How to use the Java JVM method dispatch model

WBOY
WBOYforward
2023-04-21 10:49:071339browse

1. Knowledge Reserve

1.1 Dispatch

  • Definition: The process of determining which method to execute

a. Question Some readers will ask, doesn’t the execution of the method depend on the execution object in the code settings? Why choose? b. Answer

  • If an object corresponds to multiple methods, you need to make a selection

  • Readers should They all thought of the features in Java: polymorphism, that is, rewriting & overloading. I will explain it in detail below.

  • Category: Static dispatch & dynamic dispatch. I will explain it in detail below.

1.2 Static type & dynamic type of variables

First look at the following code

public class Test { 
    static abstract class Human { 
    } 
    static class Man extends Human { 
    } 
    static class Woman extends Human { 
    } 
// 执行代码
public static void main(String[] args) { 
  Human man = new Man(); 
  // 变量man的静态类型 = 引用类型 = Human:不会被改变、在编译器可知
  // 变量man的动态类型 = 实例对象类型 = Man:会变化、在运行期才可知
    } 
}

That is:

  • Static type of variable = reference type: will not be changed, can be known at compile time

  • Dynamic type of variable = instance object type: will change, can be known at runtime

Below, I will explain in detail the types of dispatch in Java: static dispatch & dynamic dispatch

2. Static dispatch

  • Define the behavior of method dispatching based on the static type of the variable

  • That is, determine which method to execute based on the static type of the variable

  • occurs during compilation, so the Java virtual machine does not execute

  • Application scenario method overloading (OverLoad)

  • Example description

public class Test { 
// 类定义
    static abstract class Human { 
    } 
// 继承自抽象类Human
    static class Man extends Human { 
    } 
    static class Woman extends Human { 
    } 
// 可供重载的方法
    public void sayHello(Human guy) { 
        System.out.println("hello,guy!"); 
    } 
    public void sayHello(Man guy) { 
        System.out.println("hello gentleman!"); 
    } 
    public void sayHello(Woman guy) { 
        System.out.println("hello lady!"); 
    } 
// 测试代码
    public static void main(String[] args) { 
        Human man = new Man(); 
        Human woman = new Woman(); 
        Test test = new Test(); 
        test.sayHello(man); 
        test.sayHello(woman); 
    } 
}
// 运行结果
hello,guy! 
hello,guy!

According to the above explanation, everyone should understand the reason for the operation result:

  • Method overloading (OverLoad) = Static dispatch = Determine which method to execute (overload) based on the static type of the variable

  • So When the above method is executed, the overload sayHello() is determined based on the static type (Human) of the variables (man, woman) The method with the parameter Human guy, i.e. sayHello(Human guy)

Pay special attention to the

a. variable When the static type changes

You can change the static type of the variable throughforced type conversion

Human man = new Man(); 
test.sayHello((Man)man); 
// 强制类型转换
// 此时man的静态类型从 Human 变为 Man
// 所以会调用sayHello()中参数为Man guy的方法,即sayHello(Man guy)

b. Priority matching problem of static dispatch

  • Problem description:

  • The background now needs to be statically dispatched

  • The problem is not displayed in the program Specify a static type

  • The solution program will select the preferred static type for method allocation based on the priority of the static type.

Example description

public class Overload {  
    private static void sayHello(char arg){  
        System.out.println("hello char");  
    }  
    private static void sayHello(Object arg){  
        System.out.println("hello Object");  
    }  
    private static void sayHello(int arg){  
        System.out.println("hello int");  
    }  
    private static void sayHello(long arg){  
        System.out.println("hello long");  
    }  
// 测试代码
    public static void main(String[] args) {  
        sayHello('a');  
    }  
}  
// 运行结果
hello char

Because ‘a’ is a char type data (that is, the static type is char), so the overloaded method with parameter type char will be selected.

If you comment out the sayHello(char arg) method,

hello int

will be output because ‘a’ can not only represent strings, but also Can represent the number 97. Therefore When there is no most appropriate <strong>sayHello(char arg)</strong> way to overload, the second most appropriate (second priority) method will be selected Method overloading, that is, <strong>sayHello(int arg)</strong>

Summary: When there is no most suitable method for overloading, the second priority will be selected The higher method is overloaded, and so on.

The priority order is:

##char>int>long>float>double>Character>Serializable>Object>...

where

... is a variable-length parameter, which is treated as an array element. Variable-length parameters have the lowest overload priority.

Because the process of converting

char to byte or short is unsafe, the parameter type will not be selected as byte or short method is overloaded, so it is not in the priority list.

Special attention

  • The above explanation is mainly about the priority matching problem of

    basic data types

  • If it is a reference type, priority matching is performed based on the

    inheritance relationship

Note that it is only related to its compile-time type (i.e. static type)

3. Dynamic dispatch

  • Define the behavior of method dispatching based on the dynamic type of the variable

That is, determine which method to execute based on the dynamic type of the variable

  • Application scenario method override (

    Override)

  • Instance description

  • // 定义类
        class Human { 
            public void sayHello(){ 
                System.out.println("Human say hello"); 
            } 
        } 
    // 继承自 抽象类Human 并 重写sayHello()
        class Man extends Human { 
            @Override 
            protected void sayHello() { 
                System.out.println("man say hello"); 
            } 
        } 
        class Woman extends Human { 
            @Override 
            protected void sayHello() { 
                System.out.println("woman say hello"); 
            } 
        } 
    // 测试代码
        public static void main(String[] args) { 
            // 情况1
            Human man = new man(); 
            man.sayHello(); 
            // 情况2
            man = new Woman(); 
            man.sayHello(); 
        } 
    }
    // 运行结果
    man say hello
    woman say hello
    // 原因解析
    // 1. 方法重写(Override) = 动态分派 = 根据 变量的动态类型 确定执行(重写)哪个方法
    // 2. 对于情况1:根据变量(Man)的动态类型(man)确定调用man中的重写方法sayHello()
    // 3. 对于情况2:根据变量(Man)的动态类型(woman)确定调用woman中的重写方法sayHello()
Special attention

For the code:

Human man = new Man(); 
man = new Woman(); 
man.sayHello(); 
// man称为执行sayHello()方法的所有者,即接受者。

  • invokevirtualThe first step in instruction execution = Determine the actual type of the recipient

  • invokevirtual The second step of instruction execution = Resolve the class method symbol reference in the constant pool to a different direct reference

The second step is the essence of method override (Override)

4. The difference between the two

How to use the Java JVM method dispatch model

The above is the detailed content of How to use the Java JVM method dispatch model. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete