Java泛型泛型类型参数和Optionals的奇怪编译错误

时间:2017-04-02 17:13:04

标签: java generics optional raw-types

以下Java代码无法编译(使用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> } }

f1

我的问题是:为什么代码不能像上面那样编译 ,如果我将static B<Integer> f1(B a) { return null; } // program compiles with raw B 改为采用原始类型,为什么会编译:

opt.map

我的猜测是Optional<Object>被推断为返回Optional<B<Integer>>(而不是opt),但为什么?我已经查看了泛型和类型擦除(JLS 4.8)的其他问题,但它们都处理了在原始类型本身上调用方法时的情况(例如this)。这里,a不是原始的,它只需要一个原始类型参数。另外,为什么第二个版本(参数B是原始B<Object>而不是Error java: incompatible types: java.lang.Object cannot be converted to B<java.lang.Integer>)有效?

编译错误消息

{{1}}

1 个答案:

答案 0 :(得分:0)

使f1使用? 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();
    }
}