I would like to do this:
<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];
}
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];
}
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];
}
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];
}
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).