Java static binding and dynamic binding
The concept of program binding:
Binding refers to What is called is that the call of a method is associated with the class (method body) in which the method is located. For java, binding is divided into static binding and dynamic binding; or early binding and late binding.
Static binding:
The method has been bound before the program is executed (that is to say, during the compilation process, it is already known which class the method is in), which is implemented by the compiler or other linker. For example: C.
For Java, it can be simply understood as binding during program compilation; here is a special note, only final, static, private and constructor methods in Java are pre-bound
Dynamic binding:
Late binding: Binding based on the type of the specific object at runtime.
If a language implements late binding, it must also provide some mechanism to determine the type of the object during runtime and call the appropriate methods respectively. In other words, the compiler still does not know the type of the object at this time, but the method calling mechanism can investigate by itself and find the correct method body. Different languages implement late binding in different ways. But we can at least think this way: they all have to place some special type of information in the object.
The process of dynamic binding:
The virtual machine extracts the method table of the actual type of the object;
The virtual machine searches for method signatures;
Calls methods.
About the understanding that final, static, private and constructor methods are pre-bound
For private methods, first of all, it cannot be inherited. Since it cannot If it is inherited, it cannot be called through the object of its subclass, but can only be called through the object of the class itself. Therefore, it can be said that the private method is bound to the class that defines this method.
Although the final method can be inherited, it cannot be rewritten (covered). Although the subclass object can be called, the final method defined in the parent class is called. (Thus We can know that the method is declared as a final type, firstly to prevent the method from being overridden, and secondly to effectively turn off dynamic binding in Java).
Constructors cannot be inherited (it is also said on the Internet that subclasses unconditionally inherit the parameterless constructor of the parent class as its own constructor, but I personally think this statement is not appropriate, because we know that subclasses pass super( ) to call the parent class's no-argument constructor to complete the initialization of the parent class. We do not need to do this when using methods inherited from the parent class, so it should not be said that the subclass inherits the parent class's constructor), Therefore, you can also know which class this constructor belongs to during compilation.
As for the static method, I can’t explain the specific principle clearly. However, based on the information on the Internet and my own experiments, I can conclude that static methods can be inherited by subclasses, but they cannot be overridden (overridden) by subclasses, but they can be hidden by subclasses. (This means that if there is a static method in the parent class and there is no corresponding method in its subclass, then when the subclass object calls this method, the method in the parent class will be used. And if it is defined in the subclass The same method will call the method defined in the subclass. The only difference is that when the subclass object is transformed into a parent class object, the object will use the static method in the parent class regardless of whether it is defined in the subclass. Static methods. Therefore, it is said that static methods can be hidden but not overridden. This is the same as the subclass hiding the member variables in the parent class. The difference between hiding and overriding is that after the subclass object is converted into the parent class object, it can be hidden. Access the hidden variables and methods of the parent class, but cannot access the overridden methods of the parent class)
From the above we can conclude that if a method cannot be inherited or cannot be overridden after inheritance, Then this method uses static binding.
Compilation and operation of java
The compilation process of java is to compile the java source file into bytecode (jvm executable code, that is, .class file ) process, during which Java does not deal with memory. During this process, the compiler will perform syntax analysis, and an error will be reported if the syntax is incorrect.
The running process of Java refers to the jvm (java virtual machine) loading the bytecode file and interpreting it for execution. In this process, the memory layout is actually created and the java program is executed.
There are two ways to execute java bytecode: (1) Just-in-time compilation method: the interpreter first compiles the bytes into machine code, and then executes the machine code; (2) Interpretation execution method: the interpreter passes each Interpret and execute a small piece of code at a time to complete all operations of the Java bytecode program. (Here we can see that the Java program is actually converted twice during execution, first into bytecode and then into machine code. This is why Java can be compiled once and run everywhere. On different platforms By installing the corresponding java virtual machine, the same bytecode can be converted into machine code on different platforms, so as to run on different platforms)
As mentioned before, for the methods in java , except for final, static, private and constructor methods which are pre-bound, all other methods are dynamically bound.
Dynamic binding typically occurs under the conversion statement between the parent class and the subclass:
For example: Parent p = new Children();
The specific process details are as follows:
1: The compiler checks the declared type and method name of the object.
Suppose we call the x.f(args) method, and x has been declared as an object of class C, then the compiler will enumerate all methods named f in class C and all methods from class C The f method inherited from the super class.
2: Next the compiler checks the parameter types provided in the method call.
If there is a parameter type among all methods named f that best matches the parameter type provided by the call, then this method is called. This process is called "overload resolution".
3: When the program is running and a method is called using dynamic binding, the virtual machine must call a version of the method that matches the actual type of the object pointed to by x.
Assume that the actual type is D (a subclass of C). If class D defines f (String), then this method is called, otherwise the method f (String) is searched for in the super class of D. ,And so on.
When the JAVA virtual machine calls a class method (static method), it will select the method to be called based on the type of object reference (usually known at compile time). On the contrary, when the virtual machine calls an instance method, it will choose the method to be called based on the actual type of the object (which can only be known at runtime). This is dynamic binding, which is a type of polymorphism. Dynamic binding provides great flexibility for solving actual business problems and is a very beautiful mechanism.
Different from methods, when dealing with member variables (instance variables and class variables) in Java classes, runtime binding is not used, but static binding in the general sense. Therefore, in the case of upward transformation, the object's method can find the subclass, but the object's attributes (member variables) are still the attributes of the parent class (the subclass hides the parent class's member variables).
public class Father { protected String name = "父亲属性"; } public class Son extends Father { protected String name = "儿子属性"; public static void main(String[] args) { Father sample = new Son(); System.out.println("调用的属性:" + sample.name); } }
Conclusion, the called member is the attribute of the father.
This result shows that the object of the subclass (reference handle from the parent class) calls the member variable of the parent class. So it must be clear that the scope of runtime (dynamic) binding is only the method of the object.
Now I am trying to call the member variable name of the subclass. What should I do? The simplest way is to encapsulate the member variable into a getter method.
The code is as follows:
public class Father { protected String name = "父亲属性"; public String getName() { return name; } } public class Son extends Father { protected String name = "儿子属性"; public String getName() { return name; } public static void main(String[] args) { Father sample = new Son(); System.out.println("调用的属性:" + sample.getName()); } }
Result: The property of the son is called
javabecause Why should we adopt static binding method for properties? This is because static binding has many benefits. It allows us to find errors in the program at compile time instead of at runtime. This can improve the running efficiency of the program!
The above is the detailed content of Detailed explanation of java static binding and dynamic binding example code. For more information, please follow other related articles on the PHP Chinese website!