泛型 - 方法不能应用于给定类型

问题描述 投票:0回答:1

我正在阅读《Java Generics and Collections》这本书,并遇到了一个我不理解的示例。

// Original example in book
public static <T, C extends Collection<T>> C copy(C coll) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        C copy = newInstance(coll);
        copy.addAll(coll);
        return copy;
    }

public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        List<String> l = new ArrayList<>();
        l.add("something");
        copy(l);
}

我不明白的是为什么我们在

copy
方法中需要两个类型参数。如果我将方法的定义更改为下面的内容,编译器会报错

// changed method definition
public static <C extends Collection<C>> C copy(C coll) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        C copy = newInstance(coll);
        copy.addAll(coll);
        return copy;
}

编译器错误:

Error:(44, 26) java: method copy in class  cannot be applied to given types;
  required: C
  found: java.util.List<java.lang.String>
  reason: inference variable C has incompatible bounds
    upper bounds: java.util.Collection<C>
    equality constraints: java.lang.String

根据我对泛型的理解,在更改后的示例中

C=List<String>
List<String> extends Collection<String>
,那么为什么上面的代码不起作用呢?是不是类似于
T extends Comparable<T>

java generics
1个回答
0
投票

我不明白的是为什么我们在复制方法中需要两个类型参数。如果我将方法的定义更改为下面的内容,编译器会报错

// changed method definition
public static <C extends Collection<C>> C copy(C coll) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        C copy = newInstance(coll);
        copy.addAll(coll);
        return copy;
}

考虑

C extends Collection<C>
意味着
C
Collection<C>
的子类型。无论您想象
C
是什么类型,它都可能是其自身 Collection 的子类型吗?
String
是否可以是
Collection<String>
的子类型 正如前面提到的,
List<String>
可以是
Collection<List<String>>
的子类型吗?这再次暗示
String
List<String>
是同一类型。第二个参数
T
提供了一种新类型,通过将
C
T
分开来进行子类型化。

© www.soinside.com 2019 - 2024. All rights reserved.