Analysis of the implementation principle of polymorphism in Java from the perspective of virtual machine instruction execution

Source: Internet
Author: User

Analysis of the implementation principle of polymorphism in Java from the perspective of virtual machine instruction execution

A few days ago a few questions were suddenly asked by a "guy," one of which is: what is the implementation of polymorphism in Java?

I think, this certainly is not from the grammatical point of view to explain the polymorphic bar, vaguely remember that the class file format is related to the method table, but do not know when the virtual machine is executing, how to choose the correct method to execute. So, take advantage of the weekend, the bottom of the "deep understanding of Java Virtual Machine" took out, re-read the 6th, 7, 8 chapters in the content, comb: from our development tools (Intellij or Eclipse) written. Java source program, to the Javac Compiled into a class bytecode file, and then to a class bytecode file that is loaded into the virtual machine and ultimately selects the correct (polymorphic) method to perform the entire process according to the virtual machine instruction execution.

In the discussion of polymorphism (commonly called run-time polymorphism), it is inevitable to compare with overloading (overload), why? Because this involves a method called----dispatch (the name is derived from an in-depth understanding of the Java Virtual Machine, Chapter 8th 8.3. Section 2)

First look at the difference between the two from the source code (syntax):
    • Overloading (overload)

    • Override, or run-time polymorphism, is the main discussion in this article.

?

Take a look at the overloads first (the code comes from the book)

 Public classStaticdispatch {Static Abstract classHuman {}Static classMansextendshuman{}Static classWomanextendshuman{} 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 Mans(); Human woman =New Woman(); Staticdispatch sr =New Staticdispatch(); Sr.SayHello(man);//hello, Guy.Sr.SayHello(woman);//hello, Guy.}}

Take a look at the rewrite (override)

 Public classDynamicdispatch {Static Abstract classhuman{protected Abstract void SayHello(); }Static classMansextendshuman{@Override    protected void SayHello() {System. out.println("man say hello"); }    }Static classWomanextendshuman{@Override    protected void SayHello() {System. out.println("woman Say hello"); }    } Public Static void Main(string[] args) {Human man =New Mans(); Human woman =New Woman(); Man.SayHello();//man Say helloWoman.SayHello();//woman Say hello}}

In Staticdispatch.java, there is no subclass method, no parent class method. Only the SayHello method of Staticdispatch.java, that is,the receiver of the S Ayhello method is the Staticdispatch SR object , which needs to be determined according to the parameter type of the SayHello method , specifically, which of the following three methods are implemented:

    publicvoidsayHello(Human guy) {    System.out.println("hello, guy");    }    publicvoidsayHello(Man guy) {    System.out.println("hello, gentleman");    }    publicvoidsayHello(Woman guy) {    System.out.println("hello, lady");    }

In Dynamicdispatch.java, first there is a parent class human, it has a SayHello method, then there are two subclasses: Woman, man, they @override the SayHello method in the parent class, respectively. That is, the subclass overrides the method in the parent class.

The difference between overloading (overload) and overriding (Override or call run-time polymorphism) is described in terms of (source code) syntax. To execute the program, the source code must be compiled into a byte-code file first.

Now look at the difference between the two on the bytecode file

First, the Javac command compiles Staticdispatch.java and Dynamicdispatch.java into class files, and then outputs the contents of these two file bytecode using the following command, respectively:

javap -verbose StaticDispatch

The above intercepts the contents of the method table in the Staticdispatch.java Main method. The structure of the method table can refer to the description in section 6.3.6 of the book.

The code in the Main method, which is compiled into bytecode instructions by the compiler, is stored in a property named "Code" in the collection of method attribute tables.

The execution process of the main method bytecode of Staticdispatch

From the above sequence number 26 and the number 31 bytecode can be seen: sr.sayHello(man); and sr.sayHello(woman); is executed by the invokevirtual instruction.

And the symbolic references to the methods are:Method sayHello:(Lorg/hapjin/dynamic/StaticDispatch$Human;)V

Well, let's take a look at the specific execution of the invokevirtual instruction, and see how it resolves the symbolic reference to a specific method.

Because, overwrite (override) or run-time polymorphism is also through the invokevirtual instruction to choose which method to execute, so: The parsing process of the Invokevirtual directive can be said to be the principle of the implementation of polymorphism in Java.

The parsing process of the Invokevirtual directive is broadly divided into the following steps:

1. 找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C2. 如果在类型C中找到与常量中的描述符和简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束;如果不通过,则返回java.lang.IllegalAccessError异常。3. 否则,按照继承关系从下往上依次对C的各个父类进行第2步的搜索和验证过程。4. 如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常。

So, the first step is to find the actual type of the object referred to by the first element in the top of the operand stack, which is actually the actual type of the method receiver, which is the Staticdispatch object srStaticDispatch sr = new StaticDispatch()

Why is the SR object? For example, for the invokevirtual instruction of the ordinal 26, the two aload_3 and aload_1 bytecode instructions for the sequence number 24 and 25 are pushed to the top of the stack by a variable of the fourth reference type, and the second reference type variable is pushed to the top of the stack. The fourth variable of the reference type is the Staticdispatch SR object, and the second reference type is the object of the man class.Human man = new Man()

The second step is to Method sayHello:(Lorg/hapjin/dynamic/StaticDispatch$Human;)V find the simple name and descriptor of the Staticdispatch class in the same way as the constant.

Method sayHello:(Lorg/hapjin/dynamic/StaticDispatch$Human;)Vthe simple name of the constant is ' SayHello ', the descriptor information is: The returned type is empty, the parameter type is human, and there is only one argument.

In Staticdispatch.java, there are three different SayHello methods, their simple names are ' SayHello ', and the type of the parameter type ' Human ' in the descriptor is:

    publicvoidsayHello(Human guy) {    System.out.println("hello, guy");    }

Therefore, the method that sr.sayHello(man); is actually called is the public void sayHello(Human guy) method above.

Similarly, sr.sayHello(woman); the actual type of the method receiver is the Staticdispatch object Sr, which is known by ordinal 31 as the method constant or Method sayHello:(Lorg/hapjin/dynamic/StaticDispatch$Human;)V , therefore, the method actually called is stillpublic void sayHello(Human guy)

As can be seen here: for overloading (overload), its method receiver type is the same , which overload method to invoke depends on: the type of parameter passed in, the number of arguments, and so on. The parameter type is determined when the compiler generates the bytecode, such as the parameter type of the SayHello method above is human ( sayHello:(Lorg/hapjin/dynamic/StaticDispatch$Human;)V )

Therefore, sr.sayHello(man); and the sr.sayHello(woman); same method is performed public void sayHello(Human guy){} .

Next look at: Overwrite (override), also run-time polymorphic execution:

javap -verbose DynamicDispatch

The above interception is the execution of the main method of Dynamicdispatch.java. From the sequence numbers 17 and 21, it is known that the man.sayHello(); and woman.sayHello(); also are executed by the virtual machine instruction invokevirtual instruction, and the symbolic reference of the SayHello method that is called isMethod org/hapjin/dynamic/DynamicDispatch$Human.sayHello:()V

So why does the final result be: man.sayHello() output ' man say hello ', and woman.sayHello() output ' woman say hello '?

    man.sayHello();//man say hello    woman.sayHello();//woman say hello

Let's go over it again. The execution of the invokevirtual instruction. When the virtual machine executes to man.sayHello() this statement, the invokevirtual instruction first step: Find the first element in the top of the operand stack, this element is the ordinal 7 astore_1, which is a man type Object .

Next, in the second step, look for a method in the man class that matches the descriptor and simple name in the constant, where the constant is Method org/hapjin/dynamic/DynamicDispatch$Human.sayHello:()V , and the method that matches the descriptor and simple name of the constant in the man class is obviously the SayHello method in the man class.

The invokevirtual instruction then resolves the class method symbol reference in the constant pool to the direct reference of the specific SayHello method of the man class.

Similarly, woman.sayHello() when executing this statement, the first element at the top of the operand stack found by the invokevirtual instruction is an object of type woman that is stored by the instruction 15astore_2. So, in the woman class, look for a method that matches the symbolic reference of the constant pool class method Method org/hapjin/dynamic/DynamicDispatch$Human.sayHello:()V , which is the SayHello method in the woman class.

From the execution of the invokevirtual instruction above, the statement man.sayHello(); and the woman.sayHello(); corresponding class method symbol reference is the same, all org/hapjin/dynamic/DynamicDispatch$Human.sayHello:()V , but because the method recipient's actual type is different, one is the man type, the other is the woman type, Because the final execution of the method is not the same.

Some additional concepts are involved in the article:

    • Method recipient: Sr.sayhello (New Man ()), SR object is the recipient of the SayHello method
    • Constants: Constants in a constant pool, reference to item types in a constant pool
    • Descriptor: Used to describe the data type of a field, the parameter list of a method, and the return value, the parameter list of a method refers to how many arguments the method has, what type the method's arguments are, and the order of the parameters
    • Simple name: A method or field name with no type and parameter adornments. For example: The public void m(String a){} simple name is M

The above purely personal understanding, some concepts may be expressed less rigorous, if there are errors, look, thank you.

After writing this article, I looked up to the window and it was dark again. The gaze slowly moves back to the computer screen, what is the pursuit of a technical person? Which direction should I go deeper? Behind the scenes, algorithms, ML, or a big DL?

Then I think of the last conversation that the person said: The key is to see if you can continue to spend time to clear the principle behind.

Reference book: In-depth understanding of JVM virtual machines

Original: https://www.cnblogs.com/hapjin/p/9248525.html

Analysis of the implementation principle of polymorphism in Java from the perspective of virtual machine instruction execution

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.