Java dynamic binding and method overriding
Java uses static binding for overloaded methods, and dynamic binding for overridden ones. In your example, the equals method is overloaded (has a different param type than Object.equals()), so the method called is bound to the reference type at compile time.
Some discussion here
The fact that it is the equals method is not really relevant, other than it is a common mistake to overload instead of override it, which you are already aware of based on your answer to the problem in the interview.
Edit:
A good description here as well. This example is showing a similar problem related to the parameter type instead, but caused by the same issue.
I believe if the binding were actually dynamic, then any case where the caller and the parameter were an instance of Test would result in the overridden method being called. So t3.equals(o1) would be the only case that would not print.
Overridden methods and dynamic binding
No. Overriden methods cannot be resolved at compile time. They are resolved during Runtime based on type of object.
InvokeVirtual
is the Byte-code way of telling you that a method has been called.
Java Overloaded AND Overridden Methods
Since overloading and overriding both exist in this code, does that mean that it performed static binding at compile time (to the matching method in class A) and then dynamic binding at run time (to method in class B)
Right. The compiler chose the matching signature, and this is static, based on the type of the variable (A
in this case).
At runtime, Java finds the implementation of the signature selected by the compiler. This is dynamic, based on the runtime class of obj3
(B
, in this case).
Static binding and dynamic binding in Java
Trying to sum up discussion. Edit as required.
Static binding in Java occurs during Compile time while Dynamic binding occurs during Runtime.
At compile time, p1 and p2 both are types of Parent and Parent has doSmth(Object) method hence both lines binds to the same method.
p1.doSmth("String");
p2.doSmth("String");
During runtime, dynamic binding comes into picture.
p1 is instance of Child1 and Child1 has overridden doSmth(Object) hence the implementation from Child1 is used.
p2 is instance of Child2 and Child2 does NOT override doSmth(Object) hence the implementation of inherited method from Parent is called.
dynamic binding, overriding
When you are dealing with the word "static" in terms of a method or a variable, it refers that the method or a variable belong to the "class" and not its object.
When there is no object, there is no overriding.
In your class Base, you declared the main() method, in which you wrote the following statements.
Base base = new Sub();
System.out.println("Base:"+ base.foo());
Now, the reference variable type is Base and the object type is Sub. Since foo() is a static method it belongs to the class of which the reference variable is declared (i.e. Base).
Therefore, foo method of class Base is called.
Why method overloading is the best example of static binding in Java?
Method overloading is determined at compile time. The compiler decides, based on the compile time type of the parameters passed to a method call, which method having the given name should be invoked. Hence the static binding.
Method overriding is determined by the runtime type of an object. At runtime, the method that gets executed can be a method of some sub-class that wasn't even written when the code that makes the call was compiled. Hence the dynamic binding.
Binding in Java (overriding methods and fields)
The type of the variable is used to determine the class member that is accessed.
Therefore p1.x
refers to the x
field in Print1
, not the one in Print2
. (it would result in a compile time error, if you removed x
from Print1
.) The x
field in Print2
is a different field, i.e. Print2
objects have 2 different int
fields.
Also the print(B b)
method is used in the expression p1.print(c)
since Print1
doesn't have a method print(C c)
. (It would be a compile time error, if C
wouldn't extend B
or A
.) Since Print2
overrides the implementation of Print1.print(B b)
, that implementation is used.
Related Topics
Difference Between List, List<>, List<T>, List<E>, and List<Object>
How to Read JSON File into Java with Simple JSON Library
Open a Link in Browser with Java Button
Hiding Instance Variables of a Class
What Are the Differences Between Arraylist and Vector
How to Create an Asynchronous Http Request in Java
Java8: Why Is It Forbidden to Define a Default Method for a Method from Java.Lang.Object
Assert Equals Between 2 Lists in Junit
Jdk9: an Illegal Reflective Access Operation Has Occurred. Org.Python.Core.Pysystemstate
Is the Buildsessionfactory() Configuration Method Deprecated in Hibernate
How to Create 2 Separate Log Files with One Log4J Config File
Convert an Integer to an Array of Digits
Best Way to Format Multiple 'Or' Conditions in an If Statement
The Connection Between 'System.Out.Println()' and 'Tostring()' in Java
How to Increase Ide Memory Limit in Intellij Idea on MAC
Configuring Spring Security 3.X to Have Multiple Entry Points