java通用和<;中的通配符;?超级T>;下界或上界
所以我正在读关于泛型方法的书,我感到困惑。让我先在这里说明问题: 在本例中:假设我需要一个适用于任何类型T的selectionSort版本,方法是使用调用者提供的外部可比函数 第一次尝试:java通用和<;中的通配符;?超级T>;下界或上界,java,generics,wildcard,extends,bounded-wildcard,Java,Generics,Wildcard,Extends,Bounded Wildcard,所以我正在读关于泛型方法的书,我感到困惑。让我先在这里说明问题: 在本例中:假设我需要一个适用于任何类型T的selectionSort版本,方法是使用调用者提供的外部可比函数 第一次尝试: public static <T> void selectionSort(T[] arr, Comparator<T> myComparator){....} 它不会工作,因为myComparator不适用于车辆的任何子类 然后,我这样做: public static <T&g
public static <T> void selectionSort(T[] arr, Comparator<T> myComparator){....}
它不会工作,因为myComparator不适用于车辆的任何子类 然后,我这样做:
public static <T> void selectionSort(T[] arr, Comparator<? super T> myComparator){....}
publicstaticvoidselectionsort(T[]arr,Comparator这个带有疑问的短语?super T
意味着目标列表可以包含任何类型的元素
这是T
的超类型,就像源列表可能包含任何类型的元素一样
T的子类型
我们可以从集合
中看到非常简单的示例复制
:
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
public static void copy(列表首先,您可以通过将Vehicle[]
添加到Truck
来解决此问题
需要方法签名的原因
public static <T> void selectionSort(T[] arr, Comparator<? super T> myComparator)
这样就行了
Truck[] trucks = ...;
selectionSort(trucks, new TruckComparator());
selectionSort(trucks, new VehicleComparator());
因为
TruckComparator
实现Comparator
,并且Truck
等于数组的类型Truck
VehicleComparator
实现比较器
,而车辆
是阵列类型卡车的超级类型
这将不起作用
selectionSort(trucks, new BigTruckComparator());
因为bigtrackcomparator
是一个比较器
,而bigtrack
不是数组类型的超级类型Truck这两个签名在功率方面是等价的——对于任何一组参数,如果存在对其中一个有效的类型参数选择,则存在类型选择对另一个有效的参数,反之亦然
您只是在编译器中运行有限的推理。只需显式指定所需的类型参数:
YourClass.<Vehicle>selectionSort(arr, myComparator);
YourClass.selectionSort(arr,myComparator);
这将对您有所帮助。这应该对您有用,这也可能对您有所帮助。有效的Java书籍建议您记住这一点-PECS(生产者扩展
,消费者超级
)。使用extends
生成类,使用super
生成消费类。@PrasadKharkar非常感谢!博客已经准备好了,里面甚至有一个例子!“但它不起作用,因为myComparator不适用于车辆的任何子类。”这是错误的。myComparator
比较车辆
,是的。Truck[]
是车辆【】
。如果我错了,请纠正我。。所以“?超级T”可以是上界也可以是下界,这取决于我把这个短语放在哪里,对吗?super
是下界,当extends
是上界时,但是谁说T
是Truck
?如果你选择T
作为Vehicle
,那么它就起作用了。@newacct如果你仔细阅读了wuestion,哟你会看到他实例化了Truck[]arr
,然后将其传递给T[]
,因此java将T
推断为Truck
。这是毫无疑问的。当然,他的编译器可能是这样推断的。但是如果推断不足,他总是可以手动提供类型参数。你说“您需要+1,但值得一提的是,这仅是因为数组是协变的(Truck[]
是Vehicle[]
)。如果该方法采用的是列表
,则使用比较器
class Vehicle {}
class Truck extends Vehicle {}
class BigTruck extends Truck {}
class VehicleComparator implements Comparator<Vehicle> {
public int compare(Vehicle o1, Vehicle o2) {
return 0;
}
}
class BigTruckComparator implements Comparator<BigTruck> {
public int compare(BigTruck o1, BigTruck o2) {
return 0;
}
}
class TruckComparator implements Comparator<Truck> {
public int compare(Truck o1, Truck o2) {
return 0;
}
}
Truck[] trucks = ...;
selectionSort(trucks, new TruckComparator());
selectionSort(trucks, new VehicleComparator());
selectionSort(trucks, new BigTruckComparator());
YourClass.<Vehicle>selectionSort(arr, myComparator);