Java static binding and dynamic binding
Recently, I learned Java knowledge and learned static and dynamic binding of Java. Then I summarized and sorted out the corresponding knowledge on Baidu to help master this part of the knowledge.
The concept of program binding:
Binding refers to the association of a method call with the class (the method body) where the method is located. For Java, binding is divided into static binding and dynamic binding; or it is called early binding and late binding.
Static binding:
The method is bound before the program is executed (that is, you already know which class the method is in the compilation process), and it is implemented by the compiler or other connecting programs. For example: C.
It can be understood simply as binding during the program compilation period for Java; here is particularly clear that the only methods in Java are final, static, private and constructors that are pre-binding
Dynamic binding:
Later binding: binds according to the type of the specific object at runtime.
If a language implements late binding, it must also provide some mechanisms to determine the type of the object during operation and call appropriate methods separately. In other words, the compiler still does not know the object type at this time, but the method calling mechanism can investigate it by itself and find the correct method body. Different languages have different ways of implementing late binding. But we can at least think this way: they all need to install certain special types of information in the object.
Dynamic binding process:
Final, static, private and constructors are the understanding of early binding
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 can only be called through the object of this 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 overwritten (overridden). Although the child class 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 dynamic binding in java).
Constructors cannot be inherited (there are also saying that subclasses unconditionally inherit the parent class's parameterless constructor as their constructor, but I personally think this statement is inappropriate, because we know that subclasses call the parent class's parameterless constructor through super() to complete the initialization of the parent class. We do not need to do this by using methods inherited from the parent class, so it should not be said that subclasses inherit the parent class's constructor). Therefore, you can also know which class this constructor belongs to when compiling.
I can't explain the specific principles of the static method well. However, based on the online information and my own experiment, we can conclude that the static method can be inherited by subclasses, but cannot be rewritten (overridden) by subclasses, but can be hidden by subclasses. (This means that if there is a static method in the parent class and if there is no corresponding method in its subclass, then the method in the parent class will be used when the child class object calls this method. And if the same method is defined in the child class, the method defined in the child class will be called. The only difference is that when the child class object is transformed into a parent class object, regardless of whether the static method is defined in the child class, the object will use the static method in the parent class regardless of whether the child class has this static method. Therefore, it is said that static methods can be hidden but cannot be overwritten. This is the same as the child class hiding member variables in the parent class. The difference between hiding and overwritten is that after the child class object is converted into a parent class object, it can access the hidden variables and methods of the parent class, but cannot access the overwritten methods of the parent class)
From the above we can conclude that if a method cannot be inherited or cannot be overwritten after inheritance, then this method adopts static binding.
Compilation and operation of java
The java compilation process is the process of compiling the java source file into bytecode (jvm executable code, i.e. .class file). In this process, java does not deal with memory. In this process, the compiler will perform syntax analysis. If the syntax is incorrect, an error will be reported.
Java running process refers to jvm (java virtual machine) loading bytecode files and interpreting execution. In this process, it is the real creation of memory layout and execution of Java programs.
There are two ways to execute java bytecode: (1) Instant compilation method: the interpreter first compiles the bytes into machine code, and then executes the machine code; (2) Explanation execution method: the interpreter completes all operations of the java bytecode program by interpreting and executing a small piece of code each time. (Here we can see that the java program actually undergoes two conversions during the execution process, first converted into bytecode and then converted into machine code. This is also the reason why java can be compiled and run everywhere in one go. Installing the corresponding java virtual machine on different platforms can realize the same bytecode into machine code on different platforms, so as to run on different platforms)
As mentioned earlier, for the methods in Java, except for the final, static, private and constructors that are early bindings, all other methods are dynamic bindings.
The typical dynamic binding occurs under the conversion declaration of the parent class and the child class:
For example: Parent p = new Children();
The specific process details are as follows:
1: The compiler checks the declaration type and method name of the object.
Suppose we call the xf(args) method and x has been declared as an object of class C, then the compiler will list all methods named f in class C and f methods inherited from the superclass of class C.
2: Next, the compiler checks the parameter type provided in the method call.
If one parameter type among all methods with the name f matches the parameter type provided by the call the most, then this method is called. This process is called "overload resolution".
3: When the program runs and uses dynamic binding to call methods, the virtual machine must call a method version 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 the method is called, otherwise the method f (String) will be searched for in the superclass of D, and so on.
When a JAVA virtual machine calls a class method (static method), it selects the called method based on the type of object reference (usually known at compile time). On the contrary, when a virtual machine calls an instance method, it will select the called method based on the actual type of the object (only known at runtime). This is dynamic binding, which is a type of polymorphism. Dynamic binding provides great flexibility to solve actual business problems and is a very beautiful mechanism.
Unlike methods, when dealing with member variables (instance variables and class variables) in java classes, it is not a run-time binding, but a static binding in the general sense. So in the case of upward transformation, the object's method can find the subclass, while the object's attribute (member variable) is still the parent class's attribute (the subclass's hiding from the parent class member variable).
public class Father { protected String name = "father attribute"; } public class Son extends Father { protected String name = "son attribute"; public static void main(String[] args) { Father sample = new Son(); System.out.println("Called property: " + sample.name); } } Conclusion: The caller is the father's attribute.
This result shows that the object of the child class (the reference handle of the parent class) is called to the parent class member variable. Therefore, it must be clear that the category targeted by runtime (dynamic) binding is only an object's method.
Now trying to call the subclass member variable name, how to do it? The easiest way is to encapsulate the member variable into a method getter form.
The code is as follows:
public class Father { protected String name = "father attribute"; public String getName() { return name; } } public class Son extends Father { protected String name = "son attribute"; public String getName() { return name; } public static void main(String[] args) { Father sample = new Son(); System.out.println("Called property:" + sample.getName()); } } Result: The son's attribute is called
Why do Java adopt static binding methods for attributes? This is because static binding has many benefits, which allows us to discover errors in the program during the compilation period, rather than during the runtime period. This will improve the operation efficiency of the program! Dynamic binding of methods is to implement polymorphism, which is a major feature of Java. Polymorphism is also one of the key objects-oriented technologies, so it is worthwhile for Java to implement polymorphism at the cost of efficiency.
Note: Most of the above content comes from the Internet, and a small part is personal opinion and by no means authoritative remarks. If there is any inappropriate language or incorrect expression, I hope to give you advice.
Thank you for reading, I hope it can help you. Thank you for your support for this site!