Discuss / Java / 关于 copy() 方法的定义和使用的一点疑问

关于 copy() 方法的定义和使用的一点疑问

Topic source

日落有星

#1 Created at ... [Delete] [Delete and Lock User]

上文有说到:copy() 是一个静态泛型方法,在 Collections 类中这么定义

public class Collections {
    // 把src的每个元素复制到dest中:
    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
        for (int i=0; i<src.size(); i++) {
            T t = src.get(i);
            dest.add(t);
        }
    }
}

那么使用过程中这个 T 要怎么确定? 其中怎样的类型可以通过 List<? super T> dest 和 List<? extends T> src ?

比如下面:

// copy List<Integer> to List<Number> ok:
List<Number> numList = ...;
List<Integer> intList = ...;
Collections.copy(numList, intList);

此时的 copy() 方法,它的 T 应该是算什么类型? Number 还是 Integer?

List<Number> 类型可以通过 List<? super T>,List<Integer> 类型可以通过 List<? extends T>,反过来却不行。

因为上一章节讲 extends 后面都是确定的类型,比如 <? extends Number>。

但这里的 T 是什么类型呢?又是由什么确定的呢?

叁木辛尧

#2 Created at ... [Delete] [Delete and Lock User]

我想可能是因为类型擦除原因。T被编译成Object。

廖雪峰

#3 Created at ... [Delete] [Delete and Lock User]

你把Number带入T只要满足条件即可:

static <Number> void copy(List<Number>, List<Integer>)

在调用copy方法时,T是不是以传递的第一个参数的实际类型为准?第一个参数确定了T的实际类型,第二个参数就需要是继承自T或是T的子类了

在调用copy方法时,T是不是以传递的第一个参数的实际类型为准?第一个参数确定了T的实际类型,第二个参数就需要是继承自T或是T的子类

这个不对,我调换了两个参数的顺序,还是能正常执行的

方法定义和方法调用是分开的。

方法参数写法定义了这个方法的调用规范。

方法调用会根据改方法定义的规范进行检测,也就是老大说的只用把传参套上去不违背规范即可。

把Integer带入T也是满足条件的

static <Integer> void copy(List<Number> dest, List<Integer> src),只要满足参数设定的泛型类型就可带入

k

#8 Created at ... [Delete] [Delete and Lock User]

我学到这里时,也有这个疑问,想了两天,我认为应该这样理解,如果传入的两个参数是同一个类型,那么肯定满足条件,如果不同的话,第一个泛型必须是T的父类,第二个泛型必须是T的子类,画个图很好明白,这样第一个肯定是第二个的父类,你要是List<Integer> 和List<Number>反过来,条件就不成立,所以编译就报错


  • 1

Reply