Does Java List behave as a covariant type during initialisation?

abhijeetpawar :

I know that Lists in Java are Invariant.

So the second statement below gives a compilation error as expected

    List<Integer> integers = Arrays.asList(1, 2, 3);
    List<Number> numbers = integers;

However, all of these work fine

    List<Integer> numbers1 = Arrays.asList(1, 2, 3);
    List<? extends Number> numbers2 = Arrays.asList(1, 2, 3);
    List<Number> numbers3 = Arrays.asList(1, 2, 3);

So my question is how does the last statement above compile?

I understand that Arrays.asList() accepts the type from its caller, but I thought Arrays.asList(1,2,3) whould resolve to the closest type List<Integer> and setting it to List<Number> would not compile, since Lists are Invariant.

What am I missing?

dasblinkenlight :

There is no covariance going on here. Instead, Java compiler uses the context of the call to Arrays.asList<T> to infer the type T that your program wanted to specify for the method call.

Prior to Java 8 you could specify the type explicitly, for example

List<Integer> numbers1 = Arrays.<Integer>asList(1, 2, 3);
List<? extends Number> numbers2 = Arrays.<? extends Number>asList(1, 2, 3);
List<Number> numbers3 = Arrays.<Number>asList(1, 2, 3);

Noting how the above code snippets repeat the type T on both sides of the assignment, Java compiler set up inference rules to propagate T from the left side of the assignment to the right side, eliminating the repetition.

Reference: Type Inference Tutorial.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=467459&siteId=1