Java8中流处理Optional结果最大值出现类型不兼容编译错误
问题成因
这个编译错误的核心是Java对**原始类型(Raw Type)**的擦除规则导致的,和你是否用到类上的泛型参数无关:
- 当你声明
List<A> l时,A是没有传入泛型参数的原始类型,根据Java语言规范,原始类型的所有成员方法、成员变量的签名中的泛型信息会被全部擦除,哪怕这些泛型和类本身声明的类型参数没有任何关联。
对应到你的代码中,A类的getOp()方法本来的返回值是Optional<Integer>,但因为A是原始类型,该方法的返回值会被擦除为原始类型Optional,而非泛型化的Optional<Integer>。 - 原始类型
Optional的orElse()方法返回值类型为Object,而非你预期的Integer,因此map操作之后得到的流类型是Stream<Object>。 - 后续调用
max(Comparator.naturalOrder())时,Comparator.naturalOrder()返回的是要求元素实现Comparable接口的比较器,Object没有实现Comparable接口,泛型推导过程中出现类型边界冲突,最终抛出编译错误。
移除后编译正常的原因
当你移除类A上的泛型参数<T>后,A不再是泛型类,也就不存在原始类型的擦除问题,getOp()方法的返回值会保留Optional<Integer>类型,orElse(0)返回Integer类型,map后得到Stream<Integer>,而Integer本身实现了Comparable接口,完全匹配naturalOrder()比较器的类型要求,因此编译正常。
修复方案
不需要移除类A的泛型参数,只要避免使用原始类型即可,将List的声明改为:
List<A<?>> l = null;
给A传入通配符类型参数,就不会触发原始类型的全泛型擦除逻辑,代码可以正常编译。
内容的提问来源于stack exchange,提问作者petyanca
相关产品推荐
相关产品推荐

