Reputation: 15008
I'm ran into an interesting issue today. Consider the following code
public static class Parent {}
public static class Child extends Parent {}
Set<Child> childs = new HashSet();
Set<Parent> parents = (Set<Parent>)childs; //Error: inconvertible types
Parent parent = (Parent)new Child(); //works?!
Why wouldn't a cast like that work? I would expect that an implicit cast wouldn't work due to the various rules of generics, but why can't an explicit cast work?
Upvotes: 4
Views: 6901
Reputation: 38168
Though, the super type of generics work a bit differently :
Set<Child> childs = new HashSet();
Set<? extends Parent> parents = childs;
Set is the super type of set and Set
I recommend you read this docs about generics to understand that there is no inheritance between generic container just because it is not inheritance. Inheritance, before all, means specialization. Think of a box designed to hold animals, ok it could be derived by a box containing only tigers but then it would mean that box could do for tigers, of course, but also do all what the super type can do, including beeing a good box for all animals. There is something very messy for humans to think about both types of taxonomy : hyperonimic hierarchy (specialization, inheritance) and meronymic hierarchy (container/contained).
In your last line, no need to cast neither :
Parent parent = new Child();
Stéphane
Upvotes: 1
Reputation: 359786
The cast doesn't work because Java generics are not covariant.
If the compiler allowed this:
List<Child> children = new ArrayList();
List<Parent> parents = (List<Parent>)children;
then what would happen in this case?
parents.add(new Parent());
Child c = children.get(0);
The last line would attempt to assign Parent
to a Child
— but a Parent
is not a Child
!
All Child
are Parent
(since Child extends Parent
) but all Parent
are not Child
.
Upvotes: 18
Reputation: 17357
Because a Set of Childs(sic) isn't a Set of Parents. Defining a generic (parameterized) Set is effectively the same thing as defining a new class so you're defining two disjoint classes.
Upvotes: 1
Reputation: 18569
A Set<Parent>
can contain any subclass of Parent
. A Set<Child>
can contain any subclass of Child
. So a subclass of Parent
that isn't a subclass of Child
would be allowed in one but not the other, making them incompatible types.
Upvotes: 1