Java 下界通配符(可比<;?超级K>;)

Java 下界通配符(可比<;?超级K>;),java,generics,collections,wildcard,Java,Generics,Collections,Wildcard,在集合中,通常使用强制转换到可比较的接口,例如在优先级队列中: private static <T> void siftUpComparable(int k, T x, Object[] es) { Comparable<? super T> key = (Comparable<? super T>) x; ... if (key.compareTo((T) e) >= 0) break;

在集合中,通常使用强制转换到
可比较的
接口,例如在
优先级队列中

private static <T> void siftUpComparable(int k, T x, Object[] es) {
    Comparable<? super T> key = (Comparable<? super T>) x;
    ...
        if (key.compareTo((T) e) >= 0)
            break;
    ...
}
整数的任何超类
。 但我想知道为什么和如何在这里使用它。 任何例子

Comparable<T> key = (Comparable<T>) x;
可比键=(可比)x;

这还不够吗?或者使用“超级”通配符与可比通配符是一种指导原则?

泛型的全部要点是类型安全。因为Java泛型在运行时会丢失类型信息,所以我们没有验证此强制转换的方法。有界通配符是在编译时验证类型限制的一种安全方法,而不是在运行时进行hail Mary强制转换

要了解泛型中
super
extensed
的不同语义,请参阅以下线程:

E
可能不会为其自己的类实际公开可比的。想象一下这种情况:

class Foo implements Comparable<Foo> { ... }

class Bar extends Foo { ... }
类Foo实现了可比较的{…}
类栏扩展了Foo{…}

如果将优先级队列设置为
PriorityQueue
,则使用
Foo
中定义的比较方法。也就是说,你有一个
compariable放松泛型签名可以提高代码的灵活性,特别是当我们谈论参数类型时。一般准则是规则,但对于
可比
,需要这种灵活性的实际示例很少,因为这些示例意味着有一个基类型定义其所有子类型之间的自然顺序

例如,如果你有一种方法,比如

public static <T extends Comparable<T>> void sort(Collection<T> c) {

}
允许实际类型实现用超级类型参数化的
compariable
,就像已经声明的那样



对于
siftUpComparable
的特定情况,即内部收集方法没有机会确定实际的通用签名,它是否使用
Comparable
Comparable仍然无关紧要,不确定为什么需要在泛型定义中为
compariable
添加用户
super
。经过测试,这也可以在没有通配符的情况下工作。你怎么能不把
Comparable
暴露给子类呢?我的意思是
bar1.compareTo(bar2)
无论如何都是合法的(即使
compareTo
获取
Foo
type的参数)。@A.King Casting在泛型类型参数中的工作方式与在顶级类中的工作方式不同。例如,您不能直接将
列表
强制转换为
列表
,就像将
数组列表
转换为
列表一样。这就是为什么存在
通配符和
extend
/
super
语法的原因。在本例中,我似乎了解了通配符的工作原理,但它与没有通配符的选项没有什么不同。如果我显式强制转换为
Comparable
,它的编译和工作方式与
Comparable
@A.King的编译和工作方式相同。由于泛型类/方法范围的限制,您执行了一个不安全的强制转换,并且只是偶然工作。你可能有一个警告告诉你这么多。唯一的原因,这是由于在运行时类型擦除;运行时,
Comparable
Comparable
将减少为
Comparable
。在非通用上下文中,
Comparable b=(Comparable)new Bar()将无法编译,错误:不兼容类型:无法将Bar转换为可比较的
。相反,它必须定义为
可比的优秀答案!我把这看作是一种模式和我以前的工作,但我始终不明白为什么,我一直对自己说——我错过了一些东西。。。
class Foo implements Comparable<Foo> { ... }

class Bar extends Foo { ... }
public static <T extends Comparable<T>> void sort(Collection<T> c) {

}
List<LocalDate> list = new ArrayList<>();
sort(list); // does not compile
public static <T extends Comparable<? super T>> void sort(Collection<T> c) {

}