JLS illustrates this case well.
This is not covariance during initialization, as it will also work in "classic" method calls.
Note that the output strategy used in your example makes it work in Java 8, but it does not work in Java 7.
18.5.2. Conclusion type inference
Consider the example from the previous section:
List<Number> ln = Arrays.asList(1, 2.0);
The most specific applicable method has been identified as:
public static <T> List<T> asList(T... a)
In order to complete the type checking of a method call, we must determine whether it is compatible with the target type List<Number> .
The related set used to demonstrate applicability in previous section B2 was:
{ α <: Object, Integer <: α, Double <: α }
A new set of constraint formulas is as follows:
{ ‹List<α> → List<Number>› }
This compatibility constraint gives an equality estimate for α, which is part of a new connected collection, B3:
{ α <: Object, Integer <: α, Double <: α, α = Number }
These boundaries are trivially allowed:
α = Number
Finally, we perform a substitution on the declared return type asList to determine that the method call is of type List; Obviously, this is compatible with the type of target.
This output strategy is different from Java SE 7 Edition. The Java® language specification, which would have to create an instance of α based on its lower bounds (before even considering the purpose of the type call), as it was in the previous section. This will result in a type error, since the resulting type is not a subtype of List.