——Notes on deep understanding of Java virtual machine JVM advanced features and best practices
Let's start with a piece of code
public class Human {}
public class Man extends Human{}
public class Woman extends Human{}
public class FulynDemo { public void sayHello(Human arg) { System.out.println("i am human"); } public void sayHello(Man arg) { System.out.println("i am man"); } public void sayHello(Woman arg) { System.out.println("i am woman"); } public static void main(String[] args) { FulynDemo demo = new FulynDemo(); Human arg = new Human(); Human arg1 = new Man(); Human arg2 = new Woman(); demo.sayHello(arg); demo.sayHello(arg1); demo.sayHello(arg2); demo.sayHello((Man)arg1); } }
The result of the above code is:
As you can see, when overloading in java, the method to be executed is determined according to the A type parameter in A a = new B(). In this case, A is called static type or appearance type of variable, and B is called actual type. The static type of the variable itself will not be changed, and the final static type is known at compile time. However, the actual type of variables can be changed, and the result of the change can only be determined in the run-time. The actual type of variables in the compile time is unknown.
The result of the above code is that the compiler uses the static type of the parameter rather than the actual type as the judgment basis when overloading. Because the static type is known during compilation, the javac compiler will decide which version to overload according to the static type, which is a scenario of static dispatching. The following describes the definition of static dispatch: all dispatch actions that depend on static types to locate the execution version of methods are called static dispatch.
Let's look at another code example:
public class Human { public void sayHello() { System.out.println("i am human"); } }
public class Man extends Human{ @Override public void sayHello() { System.out.println("i am man"); } }
public class Woman extends Human{ @Override public void sayHello() { System.out.println("i am woman"); } }
public class FulynDemo { public static void main(String[] args) { Human arg1 = new Man(); Human arg2 = new Woman(); arg1.sayHello(); arg2.sayHello(); arg2 = new Man(); arg2.sayHello(); } }
The results of the above code execution are:
This code is obviously easy to understand, and the result will not be unexpected. This dispatching process, which determines the execution version of the method according to the actual type during operation, is called dynamic dispatching.