为何此场景下将Lambda替换为Number::doubleValue方法引用会报编译错误?
问题产生原因
- 核心原因是泛型类型推断中断:你代码中
map(person -> PersonFieldGetter.getFieldValueAsNumber(functionsParameters.getFieldName(), person))这一步,返回的Stream实际被编译器推断为Stream<Object>,而非你预期的Stream<Number>。 - 当你使用lambda写法
number -> number.doubleValue()时,编译器允许对入参做隐式类型兼容处理:哪怕上游流是Stream<Object>,lambda中的number会被自动转型为Number后再调用方法,因此可以正常编译。 - 方法引用
Number::doubleValue是严格的实例方法引用,要求上游流的元素类型必须和方法所属类型Number兼容。当上游流是Stream<Object>时,编译器会误以为你要给无参的doubleValue方法传入一个Object参数,因此抛出「实际参数和形式参数长度不匹配」的错误。 - IDEA的提示属于静态检查的误判:它是基于代码语义上
getFieldValueAsNumber返回值为Number给出的优化建议,没有考虑到编译阶段泛型推断失效的场景。
快速修复方案
你可以给map操作添加显式泛型声明,强制指定map返回的流元素类型为Number,即可正常使用方法引用:
final var fieldValuesStream = items.stream() .<Number>map(person -> PersonFieldGetter.getFieldValueAsNumber(functionsParameters.getFieldName(), person)) .mapToDouble(Number::doubleValue);
内容的提问来源于stack exchange,提问作者Mateusz Budzisz
相关产品推荐
相关产品推荐

