显式类型参数

时间:2015-01-10 09:11:32

标签: java generics

阅读Java Generics and Collections本书。

//given
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  ....
}

现在,它说 - We could also declare the above method with several possible signatures.

public static <T> void copy(List<T> dst, List<T> src)                    1
public static <T> void copy(List<T> dst, List<? extends T> src)          2  
public static <T> void copy(List<? super T> dst, List<T> src)            3
public static <T> void copy(List<? super T> dst, List<? extends T> src)  4

其中第一个限制性太强,因为它只允许在目标和源具有完全相同类型(understood)时进行调用。

其余三个对于使用隐式类型参数的调用是等效的(understood - 类型推断algo将推断出合适的类型),

Confusing part - 但显式类型参数不同。 对于上面的示例调用,第二个签名仅在type参数为Object时有效,第三个签名仅在type参数为Integer时有效。

由于我的尝试(下面)而感到困惑

public class AsList {
    public static void main (String...a) {
        List<Number> l4 = new ArrayList<Number>();
        List<Object> l5 = new ArrayList<Object>();
        List<Integer> l6 = new ArrayList<Integer>();

        //type is inferred implicitly for the below call
        copy(l4, Arrays.<Integer>asList(1, 2, 3));

        //type is specified explicitly
        AsList.<Number>copy(l4, Arrays.<Integer>asList(1, 2, 3));   \\why?  5
        AsList.<Object>copy(l5, Arrays.<Integer>asList(1, 2, 3));           6
        AsList.<Integer>copy(l6, Arrays.<Integer>asList(1, 2, 3));  \\why?  7
    }
    public static <T> void copy(List<T> dst, List<? extends T> src) {
        for (int i = 0; i < src.size(); i++) {
            dst.add(src.get(i));
        }
    }
}

此处,根据Confusing part只有6语句应该已执行但5&amp; 7也在发挥作用。为什么呢?

修改 Confusing part中提到的示例调用如下所示

Collections.copy(objs, ints);
Collections.<Object>copy(objs, ints);
Collections.<Number>copy(objs, ints);
Collections.<Integer>copy(objs, ints);

1 个答案:

答案 0 :(得分:1)

在案例5中,形式参数为List<Number>List<? extends Number>。传入List<Number>List<Integer>完全可以。

在案例7中,形式参数为List<Integer>List<? extends Integer>。再次传入List<Integer>List<Integer>很好。