In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article is about Java static binding and dynamic binding to get optimization inspiration from the example analysis, the editor feels very practical, so share with you to learn, I hope you can get something after reading this article, say no more, follow the editor to have a look.
The execution of a Java program goes through two steps: compilation and execution (interpretation). At the same time, Java is an object-oriented programming language. When the subclass and the parent class have the same method, the subclass overrides the method of the parent class, whether the program calls the method at run time to call the method of the parent class or the rewriting method of the subclass, which should be the problem we encountered when we first learned Java. First of all, we will determine which method implementation or variable operation is called binding.
There are two binding methods in Java, one is static binding, also known as early binding. The other is dynamic binding, also known as late binding.
Difference and contrast
Static binding occurs at compile time and dynamic binding occurs at run time
Variables or methods decorated with private or static or final, using static binding. Virtual methods (methods that can be overridden by subclasses) are dynamically bound based on the object at run time.
Static binding is done using class information, while dynamic binding is done using object information.
The method of overloading (Overload) is done using static binding, while the method of overriding (Override) is done using dynamic binding.
Example of overloaded method
An example of an overloaded method is shown here.
Public class TestMain {public static void main (String [] args) {String str = new String (); Caller caller = new Caller (); caller.call (str);} static class Caller {public void call (Object obj) {System.out.println ("an Object instance in Caller");} public void call (String str) {System.out.println ("a String instance in in Caller") }}}
The result of execution is
22:19$ java TestMain a String instance in in Caller
In the above code, there are two overloaded implementations of the call method, one that accepts an object of type Object as a parameter, and the other that accepts an object of type String as a parameter. Str is a String object, and all call methods that receive String type parameters are called. The binding here is a static binding based on the parameter type at compile time.
Verification
Just looking at the appearance can not prove that it is statically bound, which can be verified by compiling it with javap.
22:19$ javap-c TestMain Compiled from "TestMain.java" public class TestMain {public TestMain (); Code: 0: aload_0 1: invokespecial # 1 / / Method java/lang/Object. "": () V 4: return public static void main (java.lang.String []) Code: 0: new # 2 / / class java/lang/String 3: dup 4: invokespecial # 3 / / Method java/lang/String. ": () V 7: astore_1 8: new # 4 / / class TestMain$Caller 11: dup 12: invokespecial # 5 / / Method TestMain$Caller. "": () V 15: astore_2 16: aload_2 17: aload_1 18: invokevirtual # 6 / / Method TestMain$Caller.call: (Ljava/lang/String ) V 21: return}
You see that static binding does occur in line 18: invokevirtual # 6 / / Method TestMain$Caller.call: (Ljava/lang/String;) V, confirming that the caller method that receives the String object as a parameter is called.
An example of an override method
Public class TestMain {public static void main (String [] args) {String str = new String (); Caller caller = new SubCaller (); caller.call (str);} static class Caller {public void call (String str) {System.out.println ("a String instance in Caller") } static class SubCaller extends Caller {@ Override public void call (String str) {System.out.println ("a String instance in SubCaller");}
The result of execution is
22:27$ java TestMain a String instance in SubCaller
In the above code, there is an implementation of the call method in Caller. SubCaller inherits Caller and rewrites the implementation of the call method. We declare a variable of type Caller callerSub, but this variable points to an object of SubCaller. As you can see from the result, it calls the call method implementation of SubCaller instead of the call method of Caller. The reason for this result is that dynamic binding occurs at run time, and you need to determine which version of the call method implementation is called during the binding process.
Verification
Dynamic binding cannot be verified directly with javap, and then if it is proved that there is no static binding, then dynamic binding is done.
22:27$ javap-c TestMain Compiled from "TestMain.java" public class TestMain {public TestMain (); Code: 0: aload_0 1: invokespecial # 1 / / Method java/lang/Object. "": () V 4: return public static void main (java.lang.String []) Code: 0: new # 2 / / class java/lang/String 3: dup 4: invokespecial # 3 / / Method java/lang/String. ": () V 7: astore_1 8: new # 4 / / class TestMain$SubCaller 11: dup 12: invokespecial # 5 / / Method TestMain$SubCaller. "": () V 15: astore_2 16: aload_2 17: aload_1 18: invokevirtual # 6 / / Method TestMain$Caller.call: (Ljava/lang/String ) V 21: return}
As the result above, 18: invokevirtual # 6 / / Method TestMain$Caller.call: (Ljava/lang/String;) V here is TestMain$Caller.call rather than TestMain$SubCaller.call, because the compile time cannot determine whether to call the subclass or the implementation of the parent class, so it can only be left to the runtime dynamic binding to handle.
When overloading encounters rewriting
The following example is a bit abnormal. There are two overloads of call methods in the Caller class. What is more complicated is that SubCaller integrates Caller and overrides these two methods. In fact, this situation is a combination of the above two situations.
The following code first occurs static binding, determining that the call parameter is the call method of the String object, and then dynamically binds at run time to determine whether to execute the subclass or the call implementation of the parent class.
Public class TestMain {public static void main (String [] args) {String str = new String (); Caller callerSub = new SubCaller (); callerSub.call (str);} static class Caller {public void call (Object obj) {System.out.println ("an Object instance in Caller") } public void call (String str) {System.out.println ("a String instance in in Caller");}} static class SubCaller extends Caller {@ Override public void call (Object obj) {System.out.println ("an Object instance in SubCaller") @ Override public void call (String str) {System.out.println ("a String instance in in SubCaller");}
The execution result is
22:30$ java TestMain a String instance in in SubCaller
Verification
As already introduced above, we will only post the decompilation results here.
22:30$ javap-c TestMain Compiled from "TestMain.java" public class TestMain {public TestMain (); Code: 0: aload_0 1: invokespecial # 1 / / Method java/lang/Object. "": () V 4: return public static void main (java.lang.String []) Code: 0: new # 2 / / class java/lang/String 3: dup 4: invokespecial # 3 / / Method java/lang/String. ": () V 7: astore_1 8: new # 4 / / class TestMain$SubCaller 11: dup 12: invokespecial # 5 / / Method TestMain$SubCaller. "": () V 15: astore_2 16: aload_2 17: aload_1 18: invokevirtual # 6 / / Method TestMain$Caller.call: (Ljava/lang/String ) V 21: return}
Curious question
Does it have to be dynamic binding?
In fact, in theory, the binding of some methods can also be implemented by static binding. such as
Public static void main (String [] args) {String str = new String (); final Caller callerSub = new SubCaller (); callerSub.call (str);}
For example, where callerSub holds the object of subCaller and the callerSub variable is final, the call method is executed immediately, and the compiler can theoretically know that the call method of SubCaller should be called by analyzing enough code.
But why is there no static binding?
Suppose our Caller inherits from the BaseCaller class of a framework, which implements the call method, and BaseCaller inherits from SuperCaller. The call method is also implemented in SuperCaller.
Suppose BaseCaller and SuperCaller in a framework 1. 0
Static class SuperCaller {public void call (Object obj) {System.out.println ("an Object instance in SuperCaller");}} static class BaseCaller extends SuperCaller {public void call (Object obj) {System.out.println ("an Object instance in BaseCaller");}}
We implemented this using framework 1.0. Caller inherits from BaseCaller and calls the super.call method.
Public class TestMain {public static void main (String [] args) {Object obj = new Object (); SuperCaller callerSub = new SubCaller (); callerSub.call (obj);} static class Caller extends BaseCaller {public void call (Object obj) {System.out.println ("an Object instance in Caller"); super.call (obj) } public void call (String str) {System.out.println ("a String instance in in Caller");}} static class SubCaller extends Caller {@ Override public void call (Object obj) {System.out.println ("an Object instance in SubCaller") @ Override public void call (String str) {System.out.println ("a String instance in in SubCaller");}
Then we compiled the class file based on version 1.0 of the framework, assuming that the static binding can determine that the super.call of the above Caller is a BaseCaller.call implementation.
Then we assume again that BaseCaller in version 1.1 of the framework does not override the call method of SuperCaller, then the above assumption that the call implementation can be statically bound will be a problem in version 1.1, because on version 1.1, super.call should be implemented using the call method of SuperCall, rather than assuming that it is implemented using the call method of BaseCaller determined by static binding.
Therefore, some can actually be statically bound, considering security and consistency, they are all dynamically bound.
The enlightenment of optimization?
Because dynamic binding requires determining which version of the method implementation or variable to execute at run time, it takes more time than static binding.
So without affecting the overall design, we can consider decorating methods or variables with private,static or final.
The above is the example analysis of optimizing inspiration from Java static binding and dynamic binding. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.