我不明白为什么这段代码可以正常工作。
static <T> int compare(T t1, T t2) {
return 0;
}
public static void main(String[] args) {
compare(new Thread(), new StringBuilder());
}
因为当我们遇到这样的事情时:
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
return;
}
public static void main(String[] args) {
fromArrayToCollection(new Thread[] {}, new ArrayList<StringBuilder>()); // error
}
我们有一个错误。 为什么编译器不检查第一个例子中两个参数的匹配?抱歉提出愚蠢的问题。
最佳答案
泛型是不变的
泛型是不变,而不是协变。
这意味着,虽然您可以这样做:
Dog dog = new Dog();
Animal animal = dog; // Dog works for Animal, classes are covariant
你不能这样做:
List<Dog> dogs = List.of(new Dog());
List<Animal> animals = dogs; // Error, generics are invariant
所以 List<Dog>
是不类型List<Animal>
.但是Dog
类型为 Animal
.
当然这是有道理的,因为animals
会接受 Cat
s,但是dogs
不是。
解释
在您的第一个代码中,您没有指定要使用的类型,例如:
compare<Foo>(...)
所以你让编译器推导出类型。它搜索 Thread
的类型和 StringBuilder
有共同点,即Object
.
所以 T
解析为 Object
那里,很好:
static int compare(Object t1, Object t2) {
return 0;
}
在你的第二个例子中它不能选择Object
,因为 Collection<Object>
行为不同于 Collection<StringBuilder>
,因为泛型是不变的。因此无法找到匹配的类型,从而发生错误。
关于java - 通用方法。多个参数匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53123839/