How Does JVM Handle Polymorphism (Method Overloading and Overriding) Internally
Tags: java, polymorphism, overriding, jvm
Published: 2019-06-09 13:11:38

In my previous article [Everything About Method Overloading Vs Method Overriding](https://programmingmitra.blogspot.in/2017/05/everything-about-method-overloading-vs-method-overriding.html), I have discussed method overloading and overriding, their rules and differences.  
  
In this article, we will see How Does JVM Handle Method Overloading And Overriding Internally, how JVM identifies which method should get called.  
  
Let’s take the example of parent class`Mammal` and a child`Human` classes from our previous blog to understand it more clearly.

```java
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
    }
}
```

We can answer this answer in two ways, Logical way and Physical way, let's take a look at the logical way.  
  

Logical Way
-----------

Logically we can say, during compilation phase calling method is considered from the reference type. But at execution time method will be called from the object which the reference is holding.  
  
For Example on `humanMammal.speak();` line compiler will say `Mammal.speak()` is getting called because `humanMammal` is of type `Mammal` . But during execution JVM knows that `humanMammal` is holding a `Human's` object so `Human.speak()` will get called.  
  
Well, it is pretty simple until we keep it at the conceptual level only. Once we get the doubt that how JVM is handling all this internally? or how JVM is calculating which method it should call.  
  
Also, we know that overloaded methods are not called polymorphic and get resolved at compile time and this is why sometimes method overloading is also known as** compile-time polymorphism or early/static binding**.  
  
But overridden methods get resolved at runtime time because the compiler does not know that, the object which we are assigning to our reference have overridden the method or not.  
  

Physical Way
------------

In this section, we will try to find out physical proof of all aforementioned statements and to find them we will read the bytecode of our program which we can do by executing `javap -verbose OverridingInternalExample`. By using the `-verbose` option we will get the descriptive bytecode same as our Java program.  
  
Above command shows the bytecode in two sections  
  
**1\. Constant Pool:** holds almost everything which is necessary for our program’s execution e.g. method references (`#Methodref`), Class objects ( `#Class` ), string literals ( `#String` ), please click on image to zoom.  
  
[![java-method-area-or-constant-pool-or-method-table](https://2.bp.blogspot.com/-q3LKSKxk4B4/WT67WYY0gaI/AAAAAAAALSQ/ovoyKut4JwQU4nXBtTQntmSrgyf7HzojQCK4B/s1600/java-constant-pool-method-table.png "java-method-area-or-constant-pool-or-method-table")](//2.bp.blogspot.com/-q3LKSKxk4B4/WT67WYY0gaI/AAAAAAAALSQ/ovoyKut4JwQU4nXBtTQntmSrgyf7HzojQCK4B/s1600/java-constant-pool-method-table.png)  
  
  
**2\. Program’s Bytecode**: executable bytecode instructions, please click on image to zoom.  
  
[![method-overloading-overriding-internals-byte-code](https://4.bp.blogspot.com/-3J5Gu7HRR3U/WT67qoWNaHI/AAAAAAAALSY/mx_27LmbToA0JE151OjXF0qxHtzGfBNVACK4B/s1600/method-overloading-overriding-internals-byte-code.png "method-overloading-overriding-internals-byte-code")](//4.bp.blogspot.com/-3J5Gu7HRR3U/WT67qoWNaHI/AAAAAAAALSY/mx_27LmbToA0JE151OjXF0qxHtzGfBNVACK4B/s1600/method-overloading-overriding-internals-byte-code.png)  
  

Why Method overloading is called static binding
-----------------------------------------------

In afore-mentioned code `humanMammal.speak()` the compiler will say `speak()` is getting called from `Mammal` but at execution time it will be called from the object which `humanMammal` is holding, which is the object of the `Human` class.  
  
And by looking at the above code and images we can see that the bytecodes of `humanMammal.speak()` , `human.speak()` and `human.speak("Hindi")` are totally different because the compiler is able to differentiate between them based on the class reference.  
  
So in the case of method overloading compiler is able to identify the bytecode instructions and method’s address at compile time and that is why it is also known as **static binding or compile time polymorphism**.  
  

Why Method overriding is called dynamic binding
-----------------------------------------------

Bytecode for `anyMammal.speak()` and `humanMammal.speak()` are same ( `invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V` ) 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, according to JVM specification  
  

> invokevirtual invokes an instance method of an object, dispatching on the (virtual) type of the object. This is the normal method dispatch in the Java programming language.

  
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 (except final and static methods) because we can override every method in the child class.  
  
Operation `invokevirtual` accepts a pointer to method reference call ( `#4` an index into the constant pool)

```sh
invokevirtual #4   // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
```

And that method reference #4 again refers to a method name and Class reference

```sh
#4 = Methodref   #2.#27   // org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
#2 = Class   #25   // org/programming/mitra/exercises/OverridingInternalExample$Mammal
#25 = Utf8   org/programming/mitra/exercises/OverridingInternalExample$Mammal
#27 = NameAndType   #35:#17   // speak:()V
#35 = Utf8   speak
#17 = Utf8
```

All these references combinedly used to get a reference to a method and class in which the method is to be found. This is also mentioned in JVM Specification  
  

> The Java virtual machine does not mandate any particular internal structure for objects 4.

  
And the bookmark 4 states  
  

> In some of Oracle’s implementations of the Java virtual machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the heap for the object data.

  
It means 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.

But again the question comes, how `invokevirtual` internally do this? Well, no one can answer this because it depends on JVM implementation and it varies from JVM to JVM.  
  
And from the above statements, we can conclude that an object reference indirectly holds a reference/pointer to a table which holds all the method references of that object. Java has borrowed this concept from C++ and this table is known by various names which such as [virtual method table ( **VMT** ), virtual function table ( ** vftable** ), virtual table ( **vtable** ), dispatch table](https://en.wikipedia.org/wiki/Virtual_method_table).  
  
We can not sure how `vtable` is implemented in Java because it is JVM dependent. But we can expect that it will be following the same strategy as C++ where `vtable` is an array like structure which holds method names and their references on array indices. And whenever JVM tries to execute a virtual method it always asks the `vtable` for its address.  
  
There is only one `vtable` per class means it is unique and the same for all objects of a class similar to `Class` object. I have discussed more on `Class` object in my articles [Why an outer Java class can’t be static](https://programmingmitra.blogspot.in/2016/10/why-outer-java-class-cant-be-static.html) and [Why Java is Purely Object-Oriented Language Or Why Not](https://programmingmitra.blogspot.in/2016/06/why-java-is-purely-object-oriented-or-why-not.html).  
  
So there is only one `vtable` for `Object` class which contains all 11 methods (if we don't count registerNatives) and references to their respective method bodies.  
  
[![vtable-of-object](https://4.bp.blogspot.com/-OmB72b_upTM/WT7PkecSHMI/AAAAAAAALS0/nH5hmwdBMwMb8g-WycCsPpfn8bkh-pq3wCK4B/s640/vtable-of-object.png "vtable-of-object")](//4.bp.blogspot.com/-OmB72b_upTM/WT7PkecSHMI/AAAAAAAALS0/nH5hmwdBMwMb8g-WycCsPpfn8bkh-pq3wCK4B/s1600/vtable-of-object.png)  
  
When JVM loads the `Mammal` class into memory it creates a `Class` object for it and creates a `vtable` which contains all the methods from the vtable of Object class with the same references (Because `Mammal` is not overriding any method from Object) and adds a new entry for `speak` method.  
  
[![vtable-human](https://1.bp.blogspot.com/-asDExe0Qg18/WT7PuZdv0hI/AAAAAAAALS8/rkdwAGMRrAISOe_2mIeXTg8PTUCFxDTRQCK4B/s640/vtable-of-mammal.png "vtable-human")](//1.bp.blogspot.com/-asDExe0Qg18/WT7PuZdv0hI/AAAAAAAALS8/rkdwAGMRrAISOe_2mIeXTg8PTUCFxDTRQCK4B/s1600/vtable-of-mammal.png)  
  
  
Now here comes the turn of `Human` class and now JVM will copy all entries from the `vtable` of `Mammal` class to the `vtable` of `Human` and adds a new entry for the overloaded version of `speak(String)`.  
  
JVM knows that `Human` class has overridden two methods one is `toString()` from `Object` and second is `speck()` from `Mammal` . Now instead of creating new entries for these methods with updated references. JVM will modify the references to the already present methods on the same index where they were present earlier and will keep the same method names.  
  
[![](https://3.bp.blogspot.com/-DuoCzjUxQ8M/WT7Ru7OXi9I/AAAAAAAALTM/OHsjsEL9Bx83siSo3uKWSa5tUiL5zOiRgCK4B/s640/vtable-of-human.png)](//3.bp.blogspot.com/-DuoCzjUxQ8M/WT7Ru7OXi9I/AAAAAAAALTM/OHsjsEL9Bx83siSo3uKWSa5tUiL5zOiRgCK4B/s1600/vtable-of-human.png)
  

The `invokevirtual` causes the JVM to treat the value at method reference `#4`, not as an address but as the name of a method to look up in the `vtable` for the current object.  
  
I hope now it would have become a little bit clear that how the JVM mixes `constant pool` entries and `vtable` to conclude which method it is going to call.
  
You can find the complete code on this [Github Repository](https://github.com/njnareshjoshi/exercises/blob/master/src/org/programming/mitra/exercises/OverridingInternalExample.java) and please feel free to provide your valuable feedback.