Shmuser
Shmuser

Reputation: 202

Java method with parameterized list type parameter

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

Answers (2)

newacct
newacct

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

Mike Slinn
Mike Slinn

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

Related Questions