Reputation: 83
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
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
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
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