Implementation of the Java polymorphism

Java achieve polymorphism

Class file compilation process does not include a coupling step in a conventional compiler, all method calls are only symbolic references Class files stored inside, rather than the actual operation method in the address entry in the memory layout. This feature Java to bring a more powerful dynamic expansion of capacity, making it possible to determine the method of direct reference to certain objectives during a class operation, called Dynamic Link, also signed part of the methods used or cited for the first time in the class loading phase when converted to a direct reference, this transformation is called static resolution.

Static resolution founded on the premise that: there is a version of the method call can be determined before the program actually executed, and calls the version of this method at runtime is immutable. In other words, it is necessary to invoke the target finalized at the time of compiler, calling such methods called parsing.

In the Java language, in line with "the compiler shows that run on immutable" This method requires mainly static methods and private methods into two categories, directly associated with the former type, which can not be accessed externally, both methods by inheritance or otherwise impossible to re-write the other versions, so they are suitable resolved at class loading stage.

Java virtual machine providing a total of four byte instruction method call, namely:

invokestatic: call the static method.

invokespecial: call an instance constructor methods, private methods and the parent class method.

invokevirtual: call all virtual methods.

invokeinterface: call interface method will then determine an object of this interface at runtime.

    As long as the method can be invokestatic and invokespecial command called, can be determined only in a version called resolution phase, in line with the conditions of static methods, private methods, instance constructors and methods parent class four categories, they will be loaded in the class the direct reference symbol reference for analytical methods. These methods may be referred to as a non-virtual method (method further includes final), in contrast, another method is called virtual methods (except the final method). Here we must explain the method under final, although the final call method using invokevirtual command, but because it can not cover, there is no other version, so no need to send the other recipients multi-state selection. Java language specification clearly illustrates the final method is a non-virtual methods.

Method table and method calls

If you define Person, Gril, Boy category as follows

class Person {

public String toString() {

return "I'm a person.";

}

 

public void eat() {

}

 

public void speak() {

}

 

}

 

class Boy extends Person {

public String toString() {

return "I'm a boy";

}

 

publicvoid speak() {

}

 

public void fight() {

}

}

 

class Girl extends Person {

public String toString() {

return "I'm a girl";

}

 

public void speak() {

}

 

public void sing() {

}

}

 

When these three classes are loaded into the Java virtual machine, the method area contains information about each class. Boy Gril and method table in the process zone may be expressed as follows:

You can see, Girl and Boy methods inherited from the Object table contains the methods inherited from the direct parent Person ways and methods of their newly defined. Note that the method table entry points to the specific methods address, such as Girl inherited from Object methods, only toString () points to their realization (Girl 's method code), the rest are directed Object method code; it inherited from to Person methods eat () and Speak () pointing Person implemented method and implementation itself.                    

If a subclass rewrite the parent method, the method of the same name that subclass and superclass method of sharing a table entry.

Thus, the method table offset is always fixed. Method Table subclasses inherit all the parent class, the offset method as defined in the parent class is always a constant value.

Person 或 Object中的任意一个方法,在它们的方法表和其子类 Girl 和 Boy 的方法表中的位置 (index) 是一样的。这样 JVM 在调用实例方法其实只需要指定调用方法表中的第几个方法即可。

如调用如下:

当编译Person类的时候,生成girl.speak()的方法调用假设为:

Invokevirtual #12

设该调用代码对应着 girl.speak(); #12 是 Person 类的常量池的索引。JVM 执行该调用指令的过程如下所示:

(1)在常量池中找到方法调用的符号引用 。
(2)查看Person的方法表,得到speak方法在该方法表的偏移量(假设为15),这样就得到该方法的直接引用。 

(3)根据this指针得到具体的对象(即 girl 所指向的位于堆中的对象)。
(4)根据对象得到该对象对应的方法表,根据偏移量15查看有无重写(override)该方法,如果重写,则可以直接调用(Girl的方法表的speak项指向自身的方法而非父类);如果没有重写,则需要拿到按照继承关系从下往上的基类(这里是Person类)的方法表,同样按照这个偏移量15查看有无该方法。

Guess you like

Origin www.cnblogs.com/kexinxin/p/11546350.html