javagenericswildcardtype-parameter

Assignment of same generic types with wildcard arguments


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 )


Solution

  • 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.