How does Dynamic (run-time) polymorphism work in java? In other words how does the JVM know which methods to call?

410 views Asked by At

Say you have an arrayList of objects ArrayList<Object> arr = new ArrayList<Object>(); and you then fill this arraylist with several different objects, all of which inherit from object.

arr.add(new Integer(1));
arr.add("Im a String");
arr.add(new SomeOtherObject);

Say you then loop through the arrayList calling the .toString() method, this will actually work as expected, calling the overridden toString() methods of the String and Integer classes, what confuses me is that to the JVM, the Integer and String objects inside of the arrayList were implicitly casted into objects, so how in the world does the JVM know to caste them back into whatever they were before they were put into the arrayList? Sorry if this question has an obvious answer, but this doesnt seem to make much sense to me

3

There are 3 answers

0
Peter Lawrey On BEST ANSWER

each object has it's type stored in the header of that object. When you cast a reference to an object, this doesn't alter the object in any way.

When you call .toString for example, it looks up the method to call from the classes' description. NOTE: It doesn't have to do this every time if it can optimise the code.

0
Lajos Arpad On

Let's say you have a Foo class and you have an ArrayList<Object> called arr. When you say arr.add(new Foo()) a new object of the Foo class is added to arr as a new element. This is possible, since Foo is a class and is inherited from Object. However, the object is a Foo, even though Foo is inherited from Object. Hence, when you call its toString, it will call the toString of the Foo object you created.

Let's suppose you have an array list of Birds and Eagles fly beautifully. So, if you call the fly() method of a Bird which is in fact an Eagle, it will fly beautifully. This is in fact a great feature of inheritance and it makes very much sense.

0
Dhruv Singhal On

The truth is, JVM doesn't know how to cast them back to their original. We will have to do the task for that. Consider this... (after your lines of code)

SomeOtherObject obj = arr.get(2); //trying to access the third element

You will definitely get the compile-time error. OK now try to explicitly cast the object returned.

SomeOtherObject obj = (SomeOtherObject)arr.get(2);

It works perfectly fine! Why? Because the object returned from get() method was compatible to the type it was being casted.

Now consider this also (I know I can't do it), just for checking if JVM can tell us which object is what.

SomeOtherObject obj = (SomeOtherObject)arr.get(1); //1 instead of 2

Yes yes I know second member of this array is a String and I cannot do this. But lets see what has JVM has to say (there is no compiler error though). The message we get is that the object cannot be cast to the type specified. (But we do not get the exact type of the object).

Did you get the point? JVM here only knows that the objects being passed to this array are just objects compatible with Object. It has no idea if we actually passed the String, an int (or rather Integer, because primitives cannot be stored in collections), or SomeOtherObject (any class defined in Java is immediate subclass of Object).

Now to answer your question :

  1. (How am I able to get the String and Integer back to normal (although I will still have to type-cast them)) The reason being that String and wrapper classes (Integer is a wrapper class) have overridden toString() method inherited from Object. So printing those objects gives the actual value.

  2. (How does JVM know which type to cast them) The JVM doesn't actually know which object is to be cast into which type before returning to user. It will only return an instance of Object (that's what JVM all knows about the object). We will have to explicitly cast it to its appropriate type.

Hope I answered your question. Let me know if that's not clear.

Detailed description about runtime polymorphism (your title question) is given at this site : http://www.javatpoint.com/runtime-polymorphism-in-java