In this section, we will learn what the static and dynamic bindings are and how they work in Java.
What binding means in Java?
Let’s say you had an object of type a sub class and stored the reference of this object into a variable of type parent class. Inside the parent class, there’s a member variable named `name` and the subclass also has the same variable.
The question is: what value will be returned if we call the `name` variable via the object? Is it the variable that is defined in the parent or the one in the child class?
Let’s run the example:
The `Parent` class:
public class Parent { public String name = "Parent"; }
The `Child` class:
public class Child extends Parent { public String name = "Child"; }
The `Simple` class:
public class Simple { public static void main(String[] args) { Parent parent = new Child(); System.out.println(parent.name); } }
Output:
Parent
You can see that the value of the `Parent` class is returned!
In Java there are two rules which are called `static binding` (AKA early binding) and `dynamic binding` (AKA late binding).
These binding rules helps developers to understand beforehand that if an object of type subclass is created and stored in a variable of type parent class; what value will be returned if we called a member of that object.
Types of binding in Java:
As mentioned before, there are two types of binding in Java:
- Static binding (AKA Early Binding)
- Dynamic binding (AKA Late Binding)
Java Static binding (AKA Early Binding)
Let’s say we have an object of type subclass and the reference is stored in a variable of type base class.
If via that variable we call any member of the object that matches the list below, the one that is specified in the same class as the type of the variable will be called:
- All types of field (static and non-static)
- Static methods.
- Non-static but final methods.
In the first example of this section, we called a member variable (field or attribute) named `name` via a variable that was of type `Parent`. For this reason, the `name` variable in the `Parent` class was called and we saw its value on the screen.
This is static binding.
Example: static binding in Java
The `Parent` class:
public class Parent { public String name = "Parent"; public static void printName(){ System.out.println("I'm from parent class"); } }
The `Child` class:
public class Child extends Parent { public String name = "Child"; public static void printName(){ System.out.println("I'm from child class"); } }
The `Simple` class:
public class Simple { public static void main(String[] args) { Parent parent = new Child(); parent.printName(); } }
Output:
I’m from parent class
Note: usually it’s better to call a static method directly via the name of the class in which the static method is defined in. So don’t use an object to access a static method.
Java Dynamic Binding (AKA Late Binding)
Binding for all non-static and non-final methods follows the rules of late binding. That is, if your code accesses a non-static method, which is not declared final, the decision as to which version of the method is called is made at runtime.
This means for such type of method (non-static, non-final), it’s the type of the object that specify which method should be called.
Example: dynamic binding in Java
The `Parent` class:
public class Parent { public String name = "Parent"; public static void printName(){ System.out.println("I'm from parent class"); } public void classDescription(){ System.out.println("I'm the base class and only extend to Object class"); } }
The `Child` class:
public class Child extends Parent { public String name = "Child"; public static void printName(){ System.out.println("I'm from child class"); } @Override public void classDescription(){ System.out.println("I'm a subclass class that inherit from Parent class"); } }
The `Simple` class:
public class Simple { public static void main(String[] args) { Parent parent = new Child(); parent.classDescription(); } }
Output:
I’m a subclass class that inherit from Parent class
Here, the object is of type `Child` and its reference is stored in the `parent` variable, which is of type `Parent` class.
Now via this variable we’ve called the `classDescription()` method, which is a non-static as well as non-final method. So the target method is chosen based on the type of the object which is `Child` and so the method that is defined in this class will be called.
That’s how we got the output you saw above.
Note: if the `Child` class didn’t override the method, then in that case the method of the immediate ancestor will be the one to call. Basically, the execution engine will start from the base class and search its way through the chain until it finds the target method.