Why the following method does not give a compiler error? :
public void func3(List<? extends Number> l1, List<? extends Number> l2) {
l1 = l2;
}
Run-time error could occur in the method, but why the compiler thinks the static-type of l2
is the same as l1
? ( hence, there's no compiler error )
but why the compiler thinks the static-type of l2 is the same as l1? ( hence, there's no compiler error )
Because they are exactly the same. The compile-time type of the variables l1
and l2
are both List<? extends Number>
.
Run-time error could occur in the method
No, runtime error cannot occur. The assignment is completely safe. Anything that can be pointed to by the type of l2
can be pointed to by the type of l1
.
since wildcards are used, their types could be anything that inherits from Number.
I think you are thinking of the fact that, for example, you can pass a List<Integer>
as first argument and a List<Double>
as second argument. Yes, and that's perfectly fine. Then l1
will point to the List<Integer>
and l2
will point to the List<Double>
. Then when you do l1 = l2;
, you make both l1
and l2
point to the List<Double>
. And that's fine. Since l1
has type List<? extends Number>
, it can sometimes point to a List<Integer>
and at other times point to a List<Double>
. Consider a simpler example:
public void func4(Object o1, Object o2) {
o1 = o2;
}
I can pass a String
as first argument and an Integer
as second argument, and that's perfectly fine. The assignment o1 = o2;
will cause both o1
and o2
to point to the Integer
object, and o1
and o2
can do that since they have type Object
.