[英]Java weird compilation error with raw generic type parameter and Optionals
The following Java code doesn't compile (using javac 1.8.0_121
) 以下Java代码无法编译(使用
javac 1.8.0_121
)
import java.util.Optional;
class B<T> {}
public class Test {
static B<Integer> f1(B<Object> a) { return null; }
static B<Integer> f2() {
Optional<B> opt = Optional.empty(); // note the raw type B
return opt.map(Test::f1).get();
// error: incompatible types: Object cannot be converted to B<Integer>
}
}
My question is: Why doesn't the code compile as above , and why does it compile if I change f1
to take a raw type: 我的问题是:为什么代码不能像上面那样编译,如果我改变
f1
来获取原始类型,为什么它会编译:
static B<Integer> f1(B a) { return null; } // program compiles with raw B
My guess is that opt.map
is inferred as returning Optional<Object>
(instead of Optional<B<Integer>>
) but why? 我的猜测是
opt.map
被推断为返回Optional<Object>
(而不是Optional<B<Integer>>
),但为什么呢? I have looked at other issues with generics and type erasure (JLS 4.8), but they all deal with the situation when a method is called on a raw type itself (eg this ). 我已经查看了泛型和类型擦除(JLS 4.8)的其他问题,但它们都处理了在原始类型本身上调用方法时的情况(例如, 这 )。 Here,
opt
is not raw, it only takes a raw type parameter. 这里,
opt
不是原始的,它只需要一个原始类型参数。 Also, why does the second version (where parameter a
is raw B
instead of B<Object>
) work? 另外,为什么第二个版本(参数
a
是原始B
而不是B<Object>
)有效?
Compilation Error Message 编译错误消息
Error java: incompatible types: java.lang.Object cannot be converted to B<java.lang.Integer>
Make the f1 use a ? extends Object
让f1使用
? extends Object
? extends Object
, add a wildcard type to B
. ? extends Object
,向B
添加通配符类型。
import java.util.Optional;
class B<T> {}
public class Test {
static B<Integer> f1(B<? extends Object> a) { return null; }
static B<Integer> f2() {
Optional<B<?>> opt = Optional.empty(); // note the raw type B
return opt.map(x -> f1(x)).get();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.