具有下界类型的Java类型推断
为什么Java可以推断出多个上限类型的共同祖先,而不能推断出下限类型的共同祖先 更具体地说,考虑下面的例子:具有下界类型的Java类型推断,java,generics,type-inference,bounded-wildcard,Java,Generics,Type Inference,Bounded Wildcard,为什么Java可以推断出多个上限类型的共同祖先,而不能推断出下限类型的共同祖先 更具体地说,考虑下面的例子: static class Test { static <T> T pick(T one, T two) { return two; } static void testUpperBound() { List<? extends Integer> extendsInteger = new ArrayList
static class Test {
static <T> T pick(T one, T two) {
return two;
}
static void testUpperBound() {
List<? extends Integer> extendsInteger = new ArrayList<>();
// List<? extends Integer> is treated as a subclass of List<? extends Number>
List<? extends Number> extendsNumber = extendsInteger;
// List<? extends Number> is inferred as the common superclass
extendsNumber = pick(extendsInteger, extendsNumber);
}
static void testLowerBound() {
List<? super Number> superNumber = new ArrayList<>();
// List<? super Number> is treated as a subclass of List<? super Integer>
List<? super Integer> superInteger = superNumber;
// The inferred common type should be List<? super Integer>,
// but instead we get a compile error:
superInteger = pick(superNumber, superInteger);
// It only compiles with an explicit type argument:
superInteger = Test.<List<? super Integer>>pick(superNumber, superInteger);
}
}
静态类测试{
静态T拾取(T 1,T 2){
返回两个;
}
静态void testUpperBound(){
List我正在使用1.8.0_25,我得到了编译错误。
然而,错误不在于对pick的调用不正确,而在于要将结果放入的变量。
重复你的例子:
static void testLowerBound() {
List<? super Number> superNumber = new ArrayList<>();
List<? super Integer> superInteger = superNumber;
// this gets the error
superInteger = pick(superNumber, superInteger);
// this doesn't
pick(superNumber, superInteger);
// what's happening behind is
List<? extends Object> behind = pick(superNumber, superInteger);
superInteger = behind;
// that last line gets the same compilation error
}
static void testLowerBound(){
List我想我可以解释为什么Java区分下限类型和上限类型
如果使用不兼容的边界,例如Integer
和Long
,尝试推断公共下界可能会失败。当我们使用上界时,总是可以找到一些公共上界,在这种情况下列表您的测试使用1.8.025为我编译,没有显式类型参数。@Alex我使用的是1.7.Maybe它已经被修复了。我看不出你的推理。就像我们用扩展
将绑定转移到最近的公共超类(数字
),我们应该用超级
将它转移到最近的公共子类(整数
)。