Reputation: 202
Let's say we have two classes Parent and Child:
public class Parent {
}
public class Child extends Parent {
}
And we have method with following argument:
public void foo(List<Parent> list) {
...
}
My question why is following method arguments is illegal(case A)
List<Child> list = List.of(new Child());
foo(list); //compile error
but at the same time such case is valid(case B)
foo(List.of(new Child());
List.of()
has such signature static <E> List<E> of(E... elements)
, so i expect that
List.of(new Child())
has type List<Child>
and because of this wildcard rule(List<Child>
not extends List<Parent>
) i think that both cases must not compile.
But why case B compiles? Compiler sees, that List.of(new Child())
doesn't have explicit type and checks that every item of list can be casted to Parent.class
and do it to obtain correct type?
Upvotes: 2
Views: 786
Reputation: 122429
Java generics are invariant. List<Child>
is not a subtype of List<Parent>
.
In the second case, the parameter of foo()
requires type List<Parent>
, which forces List.of()
to be inferred with E
being Parent
(i.e. List.<Parent>of(new Child())
). Notice that new Child()
can be passed to List.<Parent>of()
since Child
is a subtype of Parent
.
Upvotes: 4
Reputation: 8403
This should work:
List<Parent> list = List.of(new Child());
foo(list);
You can assign a list of subtypes to a variable declared as a list of types.
You can not pass a list of types to a method declared to accept a list of subtypes.
Upvotes: -1