为什么这个 Java 带有限定通配符的泛型代码不能编译?
Why this Java generic code with bounded wildcard doesn't compile?
当我阅读这个我无法理解的源代码示例时,我正在阅读 superb Java Generics FAQ by Angelika Langer:
import java.util.List;
import java.util.ArrayList;
import java.lang.Number;
import java.lang.String;
import java.lang.Long;
class X<T extends List<? extends Number>> {
public void someMethod(T t) {
t.add(new Long(0L)); // error
Number n = t.remove(0);
}
}
我不明白为什么编译器不能推断出 "Long extends Number" 并在类型擦除之前将其与“?extends Number”匹配,从而使 <? extends Number>
完全无用。
我已经阅读了常见问题解答,所以我正在寻找更简单的解释以及替代方案。
提前致谢
假设有人这样使用您的class:
List<Double> list = new ArrayList<>();
X<List<Double>> x = new X<>();
x.someMethod(list);
现在您的方法将尝试将 Long
添加到 List<Double>
。这就是编译器不允许的原因。
您不能将 Long
添加到 List<? extends Number>
,因为 List<? extends Number>
可以分配给 List<Double>
、List<Integer>
等...
您可以将 class 声明更改为 X<T extends List<Number>>
,这将解决编译错误,因为对于 List<Number>
您始终可以添加 Long
(或Number
).
的任何其他子 class 的实例
当我阅读这个我无法理解的源代码示例时,我正在阅读 superb Java Generics FAQ by Angelika Langer:
import java.util.List;
import java.util.ArrayList;
import java.lang.Number;
import java.lang.String;
import java.lang.Long;
class X<T extends List<? extends Number>> {
public void someMethod(T t) {
t.add(new Long(0L)); // error
Number n = t.remove(0);
}
}
我不明白为什么编译器不能推断出 "Long extends Number" 并在类型擦除之前将其与“?extends Number”匹配,从而使 <? extends Number>
完全无用。
我已经阅读了常见问题解答,所以我正在寻找更简单的解释以及替代方案。
提前致谢
假设有人这样使用您的class:
List<Double> list = new ArrayList<>();
X<List<Double>> x = new X<>();
x.someMethod(list);
现在您的方法将尝试将 Long
添加到 List<Double>
。这就是编译器不允许的原因。
您不能将 Long
添加到 List<? extends Number>
,因为 List<? extends Number>
可以分配给 List<Double>
、List<Integer>
等...
您可以将 class 声明更改为 X<T extends List<Number>>
,这将解决编译错误,因为对于 List<Number>
您始终可以添加 Long
(或Number
).