Static Vs. Dynamic Binding in Java

I'm currently doing an assignment for one of my classes, and in it, I have to give examples, using Java syntax, of static and dynamic binding. I understand the basic concept, that static binding happens at compile time and dynamic binding happens at runtime, but I can't figure out how they actually work specifically. I found an example of static binding online that gives this example:

public static void callEat(Animal animal) < System.out.println("Animal is eating"); >public static void callEat(Dog dog) < System.out.println("Dog is eating"); >public static void main(String args[])

And that this would print "animal is eating" because the call to callEat uses static binding, but I'm unsure as to why this is considered static binding. So far none of the sources I've seen have managed to explain this in a way that I can follow.

15.9k 34 34 gold badges 118 118 silver badges 210 210 bronze badges asked Sep 26, 2013 at 0:15 user2309750 user2309750 1,557 4 4 gold badges 14 14 silver badges 11 11 bronze badges Commented Sep 26, 2013 at 0:22

Note that there are several different concepts that are referred to as "binding". In this particular case, for this type of binding (which involves a choice between similar but not identical method "signatures") the compiler (which makes "static" decisions, since they do not vary at run time) decides that the parameter is an "Animal" because that is the (static) type of the variable "a".

Commented Sep 26, 2013 at 0:56

(There are languages where the choice of the specific method signature would be left until runtime, and callEat(Dog) would be selected.)

Commented Sep 26, 2013 at 1:27

9 Answers 9

  1. Static binding in Java occurs during compile time while dynamic binding occurs during runtime.
  2. private , final and static methods and variables use static binding and are bonded by compiler while virtual methods are bonded during runtime based upon runtime object.
  3. Static binding uses Type ( class in Java) information for binding while dynamic binding uses object to resolve binding.
  4. Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime.
public class StaticBindingTest < public static void main(String args[]) < Collection c = new HashSet(); StaticBindingTest et = new StaticBindingTest(); et.sort(c); >//overloaded method takes Collection argument public Collection sort(Collection c) < System.out.println("Inside Collection sort method"); return c; >//another overloaded method which takes HashSet argument which is sub class public Collection sort(HashSet hs) < System.out.println("Inside HashSet sort method"); return hs; >> 

Output: Inside Collection sort method

Example of Dynamic Binding in Java

public class DynamicBindingTest < public static void main(String args[]) < Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car vehicle.start(); //Car's start called because start() is overridden method >> class Vehicle < public void start() < System.out.println("Inside start method of Vehicle"); >> class Car extends Vehicle < @Override public void start() < System.out.println("Inside start method of Car"); >> 

Output: Inside start method of Car

13.8k 13 13 gold badges 68 68 silver badges 85 85 bronze badges answered Feb 25, 2014 at 6:14 Maulik Patel Maulik Patel 2,792 4 4 gold badges 22 22 silver badges 28 28 bronze badges and is from javarevisited.blogspot.in/2012/03/… Commented Oct 15, 2014 at 14:07 I still don't understand the difference, Commented Oct 12, 2016 at 18:29

@technazi static binding just looks at the type (what ever is before the equals e.g Collection c = new HashSet(); so it will be seen as just a collection object when infact it is a hashset). Dyanmic binding takes into account the actual object (whats after the equals so it actually recognises its a HashSet).

Commented Apr 19, 2017 at 10:39

Very good example. But I am confused with this scenario. Lets say StaticBindingTestChild extends StaticBindingTest and overrided botht the overloaded methods. Now if we do something like this: Collection c = new HashSet(); StaticBindingTest et = new StaticBindingTestChild(); et.sort(c); will it be static or dynamic binding?

Commented Sep 2, 2021 at 10:15

For another discussion and example on what late or dynamic binding is you may also want to look at this question: stackoverflow.com/questions/19098459/…

Commented Oct 9, 2021 at 13:24

Connecting a method call to the method body is known as Binding. As Maulik said "Static binding uses Type(Class in Java) information for binding while Dynamic binding uses Object to resolve binding." So this code :

public class Animal < void eat() < System.out.println("animal is eating. "); >> class Dog extends Animal < public static void main(String args[]) < Animal a = new Dog(); a.eat(); // prints >> dog is eating. > @Override void eat() < System.out.println("dog is eating. "); >> 

Will produce the result: dog is eating. because it is using the object reference to find which method to use. If we change the above code to this:

class Animal < static void eat() < System.out.println("animal is eating. "); >> class Dog extends Animal < public static void main(String args[]) < Animal a = new Dog(); a.eat(); // prints >> animal is eating. > static void eat() < System.out.println("dog is eating. "); >> 

It will produce : animal is eating. because it is a static method, so it is using Type (in this case Animal) to resolve which static method to call. Beside static methods private and final methods use the same approach.

2,900 31 31 silver badges 24 24 bronze badges answered Jul 8, 2016 at 8:15 4,444 3 3 gold badges 46 46 silver badges 40 40 bronze badges Why can't Java deduce that a is actually a Dog at compile time? Commented Jun 9, 2020 at 4:19

Well in order to understand how static and dynamic binding actually works? or how they are identified by compiler and JVM?

Let's take below example where Mammal is a parent class which has a method speak() and Human class extends Mammal , overrides the speak() method and then again overloads it with speak(String language) .

public class OverridingInternalExample < private static class Mammal < public void speak() < System.out.println("ohlllalalalalalaoaoaoa"); >> private static class Human extends Mammal < @Override public void speak() < System.out.println("Hello"); >// Valid overload of speak public void speak(String language) < if (language.equals("Hindi")) System.out.println("Namaste"); else System.out.println("Hello"); >@Override public String toString() < return "Human Class"; >> // Code below contains the output and bytecode of the method calls public static void main(String[] args) < Mammal anyMammal = new Mammal(); anyMammal.speak(); // Output - ohlllalalalalalaoaoaoa // 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V Mammal humanMammal = new Human(); humanMammal.speak(); // Output - Hello // 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V Human human = new Human(); human.speak(); // Output - Hello // 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V human.speak("Hindi"); // Output - Namaste // 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V >> 

When we compile the above code and try to look at the bytecode using javap -verbose OverridingInternalExample , we can see that compiler generates a constant table where it assigns integer codes to every method call and byte code for the program which I have extracted and included in the program itself (see the comments below every method call)

Program Bytecode

By looking at above code we can see that the bytecodes of humanMammal.speak() , human.speak() and human.speak("Hindi") are totally different ( invokevirtual #4 , invokevirtual #7 , invokevirtual #9 ) because the compiler is able to differentiate between them based on the argument list and class reference. Because all of this get resolved at compile time statically that is why Method Overloading is known as Static Polymorphism or Static Binding.

But bytecode for anyMammal.speak() and humanMammal.speak() is same ( invokevirtual #4 ) because according to compiler both methods are called on Mammal reference.

So now the question comes if both method calls have same bytecode then how does JVM know which method to call?

Well, the answer is hidden in the bytecode itself and it is invokevirtual instruction set. JVM uses the invokevirtual instruction to invoke Java equivalent of the C++ virtual methods. In C++ if we want to override one method in another class we need to declare it as virtual, But in Java, all methods are virtual by default because we can override every method in the child class (except private, final and static methods).

In Java, every reference variable holds two hidden pointers

  1. A pointer to a table which again holds methods of the object and a pointer to the Class object. e.g. [speak(), speak(String) Class object]
  2. A pointer to the memory allocated on the heap for that object’s data e.g. values of instance variables.

So all object references indirectly hold a reference to a table which holds all the method references of that object. Java has borrowed this concept from C++ and this table is known as virtual table (vtable).

A vtable is an array like structure which holds virtual method names and their references on array indices. JVM creates only one vtable per class when it loads the class into memory.

So whenever JVM encounter with a invokevirtual instruction set, it checks the vtable of that class for the method reference and invokes the specific method which in our case is the method from a object not the reference.

Because all of this get resolved at runtime only and at runtime JVM gets to know which method to invoke, that is why Method Overriding is known as Dynamic Polymorphism or simply Polymorphism or Dynamic Binding.