gpt4 book ai didi

Java 泛型方法不能调用另一个具有更宽松约束的泛型方法并返回其值

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:42:53 26 4
gpt4 key购买 nike

我想这样做:

<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> .

作为Johannes Kuhn在他的 comment 中指出, Date 的一个子类将隐式实现 Comparable<Date>而不是 Comparable<DateSubclass> ,因此需要 Comparable<? super T> .

有关详细信息,请参阅:What is PECS (Producer Extends Consumer Super)?

关于Java 泛型方法不能调用另一个具有更宽松约束的泛型方法并返回其值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57974748/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com