问题描述
我想这样做:
<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
中插入强制类型转换,否则它将无法编译:
But it fails to compile unless I insert a cast within 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
中删除了通用名称,那么它将起作用:
Interestingly, if I remove the generic from a
it works:
java.util.Date a(java.util.Date... dates) {
return b(dates);
}
<T extends Comparable<T>> T b(T... comparables) {
return comparables[0];
}
如果我将原始代码移植到Kotlin,它也可以工作(这使我认为这是Java的局限性,而不是根本上不可知的东西):
And if I port the original code to Kotlin, it also works (this makes me think it's a limitation of Java, and not something that is fundamentally unknowable):
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编译器可以将强制类型转换插入幕后(据我所知,是在其他情况下如何实现泛型的方法.
My question is: what is special about Java's type system that prevents this from compiling? It feels to me like the Java compiler could just insert the cast behind the scenes (it is my understanding that that is how generics are implemented in other cases).
推荐答案
不需要强制转换就可以编译它.相反,当指定T
必须扩展Comparable<T>
时,可以使用有界通配符:
A cast isn't required to get this to compile. Instead, you can use a bounded wildcard when specifying that T
must extend 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>
.
Johannes Kuhn 在他的评论,Date
的子类将隐式实现Comparable<Date>
而不是Comparable<DateSubclass>
,因此需要Comparable<? super T>
.
As Johannes Kuhn pointed out in his comment, a subclass of Date
will implicitly implement Comparable<Date>
instead of Comparable<DateSubclass>
, hence the need for Comparable<? super T>
.
有关更多信息,请参见:什么是PECS(生产者扩展了超级消费者) ?
For more information, see: What is PECS (Producer Extends Consumer Super)?
这篇关于Java通用方法无法调用约束更宽松的另一个通用方法并返回其值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!