You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两种Lambda创建Predicate的写法差异及编译失败原因咨询

为什么两种Predicate组合写法的编译结果不同?

咱们先从Predicate.isEqual的方法签名入手,它的定义是:

static <T> Predicate<T> isEqual(Object targetRef)

这个静态方法的泛型参数<T>是根据调用时的上下文来推断的,这就是两种写法差异的核心。

写法1编译失败的原因

看这句代码:

Predicate<Integer> predicate = Predicate.isEqual(0).or(Predicate.isEqual(1));

编译器在处理链式调用时,会先单独解析第一个Predicate.isEqual(0)。这时候,因为还没看到后续的.or()调用和左边的赋值目标类型,它只能根据传入的参数0(虽为Integer类型,但方法参数是Object)推断泛型<T>为Object,所以第一个isEqual返回的是Predicate<Object>。

接下来调用.or()方法时,传入的Predicate.isEqual(1)也会被编译器推断为Predicate<Object>(因为.or()的参数需要和前面的Predicate类型匹配),所以整个链式调用的结果是Predicate<Object>,而你要把它赋值给Predicate<Integer>,类型不兼容,自然编译报错。

写法2能正常运行的原因

再看分步写的代码:

Predicate<Integer> pred21 = Predicate.isEqual(0);
Predicate<Integer> pred22 = pred21.or(Predicate.isEqual(1));

第一步,当你把Predicate.isEqual(0)赋值给Predicate<Integer>类型的变量时,编译器明确知道泛型<T>应该是Integer,所以pred21是Predicate<Integer>类型。

第二步调用.or()方法时,pred21的.or()方法签名是default Predicate<T> or(Predicate<? super T> other),这里的T是Integer,所以参数other可以是Predicate<? super Integer>。这时候传入的Predicate.isEqual(1)会根据这个上下文推断泛型<T>为Integer,返回Predicate<Integer>,完全符合.or()的参数要求,最终返回的结果也是Predicate<Integer>,可以正常赋值给pred22。

优化写法1的小技巧

如果想保持单语句写法,你可以显式指定泛型参数,帮编译器明确类型:

Predicate<Integer> predicate = Predicate.<Integer>isEqual(0).or(Predicate.isEqual(1));

这样第一个isEqual的泛型<T>被指定为Integer,后续的.or()也会沿用这个类型,就能正常编译了。

内容的提问来源于stack exchange,提问作者daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:40:22