Java's static binding and dynamic binding

We can think about a question:

How does the JVM know which class's method source code is being called? What's the inside story here?

In this article, we will expose the static binding and dynamic binding mechanism (auto binding) of JVM method calls .

Before understanding these two bindings, we might as well understand the word binding first.

What is binding?

Binding in Java refers to the association of a method call with the class (method body) where the method is located.

Binding in Java is divided into static binding and dynamic binding; or called early binding or late binding.

static binding

The method has been bound before the program is executed. For Java, it can be simply understood as the binding of the program compilation time ;

What does this sentence mean? That is, at compile time, we know which class the method corresponds to.

For the methods in Java, only final, static, private and constructor methods are early bound.

We can simply write two demos:

public class Father {
    public static final void f1(){
        System.out.println("Father-f1()");
    }
}
public class StaticCall {
    public static void main(String[] args) {
        Father.f1();
    }
}

Let's simply analyze the bytecode file (here we strongly recommend a plug-in jclasslib for IDEA to see the bytecode)

 We can see that the JVM in the corresponding first line puts the f1() method into the constant pool through invokespecial, and then finds the direct address of the f1() method in the method area where the Father class is located, and transfers the direct address Recorded in the constant table in the constant pool of the StaticCall class. This process is called constant pool analysis . When calling Father.f1() again in the future, the bytecode of the f1 method will be found directly.

Through the above process, we found that after the constant pool analysis, the JVM can determine where the f1() method to be called is located in the memory. In fact, this information has been recorded in the constant pool of the StaticCall class during the compilation phase. This way of determining which method to call at the compilation stage is called a static binding mechanism.

Except for static methods modified by static, all private methods modified by private and methods that are prohibited from being overridden by subclasses modified by final will be compiled into invokestatic instructions. In addition, the initialization methods <init> and <clinit> of all classes will be compiled into invokespecial instructions. The JVM will use the static binding mechanism to smoothly call these methods.

final: Although the final method can be inherited, it cannot be overridden (covered). Although the subclass object can be called, the final method defined in the parent class is called (from this we can know that the method is declared as final type, one is to prevent the method from being overwritten, and the other is to effectively close the dynamic binding in java).

private: For the private method, first of all, it cannot be inherited. Since it cannot be inherited, there is no way to call it through the object of its subclass, but only through the object of this class itself. Therefore, it can be said that the private method is bound to the class that defines the method.

dynamic binding

That is, the object is bound inline at runtime .

Bind at runtime based on the type of the concrete object. Some mechanisms are provided to determine the type of the object during runtime and call the appropriate method respectively. In other words, the compiler still does not know the type of the object at this time, but the method call mechanism can investigate by itself and find the correct method body.

In fact, when do we need to use our dynamic binding? That is to say, when we need to bind objects at runtime, it is not difficult for us to think of inheritance. We need to make dynamic binding.

Because when we use a subclass, if the method of the subclass is overwritten, then our method binding needs to be changed at this time. This is actually a way of polymorphism in our Java.

Reference article: https://blog.csdn.net/zhangjk1993/article/details/24066085

Guess you like

Origin blog.csdn.net/weixin_43918614/article/details/124450025