gpt4 book ai didi

Java 泛型捕获列表

转载 作者:搜寻专家 更新时间:2023-10-31 08:15:31 33 4
gpt4 key购买 nike

我正在查看 Java Generics documentation并找到了这段代码,

public class WildcardError {

void foo(List<?> l) {
//This give a compile time error
l.set(0,l.get(0));
}
}

我可以理解我们正在从 List<?> 中获取一个元素并尝试将其设置为另一个 List<?> .所以编译器报错。我的问题是,当两个列表不同时,即 l.set(0, m.get(0)) 是有意义的这里列出了 lm是不同的。但在上面的例子中,ll是相同的列表。为什么编译器不够聪明,看不到这一点?实现起来难吗?

编辑:我知道我可以通过辅助方法或使用 T 来修复它而不是 ? .只是想知道为什么编译器不为我做这件事。

最佳答案

在你的具体情况下,你可以明确地解决这个问题:

public class WildcardError {
<T> void foo(List<T> l) {
// This will work
l.set(0, l.get(0));
}
}

或者如果你不想改变原有的API,引入一个delegate helper方法:

public class WildcardError {
void foo(List<?> l) {
foo0(l);
}

private <T> void foo0(List<T> l) {
// This will work
l.set(0, l.get(0));
}
}

不幸的是,编译器无法推断出“显而易见的”<T>类型。我也一直在想这个。这似乎可以在编译器中进行改进,因为每个通配符都可以非正式地转换为未知的 <T>类型。可能有一些原因导致它被省略,也许这只是直觉,但形式上是不可能的。

更新:

请注意,我刚刚看到了 Collections.swap() 的这个特殊实现:

public static void swap(List<?> list, int i, int j) {
final List l = list;
l.set(i, l.set(j, l.get(i)));
}

为了在本地处理这个问题,JDK 人员求助于原始类型。这是一个强有力的声明,表明编译器可能应该支持它,但由于某些原因(例如,没有时间正式指定它)还没有完成

关于Java 泛型捕获列表<?>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11499989/

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