我想这样做:
<T extends java.util.Date> T a(@Nonnull T... dates) {
return b(dates); // compile error
}
<T extends Comparable<T>> T b(T... comparables) {
return comparables[0];
}
但除非我在其中插入强制转换,否则它无法编译a
:
<T extends java.util.Date> T a(@Nonnull T... dates) {
return (T) b(dates); // warning about unsafe cast in IntelliJ
}
<T extends Comparable<T>> T b(T... comparables) {
return comparables[0];
}
有趣的是,如果我从a
有用:
java.util.Date a(java.util.Date... dates) {
return b(dates);
}
<T extends Comparable<T>> T b(T... comparables) {
return comparables[0];
}
如果我将原始代码移植到 Kotlin,它也可以工作(这让我认为这是 Java 的限制,而不是根本上不可知的东西):
fun <T: java.util.Date> a(dates: Array<T>): T {
return b(dates);
}
fun <T: Comparable<T>> b(comparables: Array<T>): T {
return comparables[0];
}
我的问题是:Java 的类型系统有什么特别之处会阻止编译?在我看来,Java 编译器可以在幕后插入强制转换(据我所知,这就是在其他情况下实现泛型的方式)。
不需要强制转换即可编译它。相反,您可以在指定时使用有界通配符T
必须延长Comparable<T>
:
<T extends java.util.Date> T a(T... dates) {
return b(dates); // compiles fine
}
<T extends Comparable<? super T>> T b(T... comparables) {
return comparables[0];
}
请注意Comparable<? super T>
代替Comparable<T>
.
As 约翰内斯·库恩 https://stackoverflow.com/users/845414/johannes-kuhn在他的书中指出comment https://stackoverflow.com/questions/57974748/java-generic-method-cannot-call-another-generic-method-with-looser-constraint-an/57975038#comment102360015_57975038,一个子类Date
将隐式实现Comparable<Date>
代替Comparable<DateSubclass>
,因此需要Comparable<? super T>
.
有关更多信息,请参阅:什么是 PECS(生产者扩展消费者超级)? https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)