Aayush Taneja
Aayush Taneja

Reputation: 83

Type Mismatch with polymorphism in ArrayLists

Here is my code:-

ArrayList<animal> myanimals = new ArrayList<animal>();
dog adog = new dog();
myanimals.add(adog);
System.out.println("" + myanimals.get(0).getClass());
dog newdog = myanimals.get(0);

I have created an ArrayList of animals(superclass) as myanimals and stored a dog(subclass) as the first element. Then myanimals.get(0) returns a dog type object. When this dog type object is referred by a dog type reference in the statement dog newdog = myanimals.get(0), it shows an error saying :

Type mismatch, cannot convert from animal to dog.

Why does this happen?

Upvotes: 1

Views: 421

Answers (3)

iTollu
iTollu

Reputation: 1069

Java is a statically typed language. I.e. Java compiler checks code for type mismatches based on source code. And your source code says, that myanimals.get(0) is of type Animal.

Inheritance is a "IS-A" relationship, i.e. Dog IS-A Animal and can be used as value for variables of type Animal. But the reverse is not true: Animal not IS-A Dog, it just could be (which makes casting possible - more on that later). That's why you get type mismatch.

It is only in runtime, long after your source code had been compiled into bytecode (and generics types erased), that myanimals.get(0).getClass() appears to be Dog by coincidence. Compiler couldn't know that before.

This makes sense: it prevents runtime errors that could be caught by static analysis.

But it's you, the developer, who knows for sure, that myanimals.get(0).getClass() will be of type Dog at runtime, so you can take responsibility and apply casting as in Shashwat's answer. Compiler still checks if such casting is possible at all, and if yes - it would believe your word.

Upvotes: 2

dumbPotato21
dumbPotato21

Reputation: 5695

The method call myanimals.get(0) returns an object reference of type Animal. Try Typecasating that Animal as a dog like :-

dog newdog = (dog)myanimals.get(0);

Edit 1: You asked about the output of the following line

System.out.println(myanimals.get(0).getClass());

This actually prints out dog. Why ? Let's get some perspective.

What do you think the following program should output:

animal a = new dog();
System.out.println(a.getClass());

This prints out dog as expected. But this doesn't mean that we can do this:-

animal a = new dog();
dog d = a;

This would throw a Compile-Time error. The Same is the problem with your case. The ArrayList is said to contain animal. Therefore, it would return animal even though you added a dog to it.

Upvotes: 4

Renats Stozkovs
Renats Stozkovs

Reputation: 2605

Basically, the type of an ArrayList is animal and you could add any kind of animals in there, not just dogs but cats, mice and parrots. While the underlying type is indeed dog in your case, you can't safely know this. Otherwise you'd run into runtime exceptions as in this scenario:

ArrayList<Animal> myanimals = new ArrayList<Animal>();
Cat myCat = new Cat();
myanimals.add(myCat);
System.out.println("" + myanimals.get(0).getClass());
Dog newdog = myanimals.get(0); // <-- this would be runtime exception if Java compiler allowed this

Upvotes: 0

Related Questions