2

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?

3
  • just do this instead of case B: List<Parent> plist = List.of(new Child()); foo(plist); See what happens? The same as in your case B - but explicitly. While your case A sets the type of the list to sth. different. BTW. you don't have a function but rather a method foo. Commented Mar 30, 2021 at 19:18
  • change your method signature to foo(List<? extends Parent> list) to accept descendants of Parent. Commented Mar 30, 2021 at 19:32
  • @juwil just as i thought, thanks! Commented Mar 30, 2021 at 19:33

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

Comments

-1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.