Lambda 作为 Predicate 接口中方法的组合,如果它被写成一条语句则无法编译
Lambda as a combination of methods from the Predicate interface doesn't compile if it is written as one statement
这两种创建 lambda 的方式有什么区别?为什么第一个不编译?
Predicate<Integer> predicate = Predicate.isEqual(0).or(Predicate.isEqual(1));
给出:
错误:类型不兼容:Predicate<Object>
无法转换为 Predicate<Integer> = Predicate.isEqual(0).or(Predicate.isEqual(1));
Predicate<Integer> pred21 = Predicate.isEqual(0);
Predicate<Integer> pred22 = pred21.or(Predicate.isEqual(1));
这个有效。
在 isEqual
方法调用之前添加 <Integer>
应该会有所帮助:
Predicate<Integer> predicate = Predicate.<Integer>isEqual(0).or(Predicate.isEqual(1));
这种编译器行为背后的原因:
isEqual
是一个静态泛型方法,它 returns Predicate<T>
(不管它的输入参数的实际类型是什么),所以它 returns Predicate<Object>
在调用方法时未明确指定返回类型。
or
也是一个静态泛型方法,但是它 returns 一个谓词参数化了相同的类型,作为它的输入参数(即 Predicate<Object>
)。
发生这种情况是因为
Predicate.isEqual(0)
有这个签名:
static <T> Predicate<T> isEqual(Object targetRef)
如果您不输入它,它会推断 Predicate<Object>
。
要键入它,您可以键入 return 类型
Predicate<Integer> pred21 = Predicate.isEqual(0);
或像这样输入电话
Preicate.<Integer>isEqual
看签名:
static <T> Predicate<T> isEqual(Object targetRef)
在第一个例子中,编译器无法猜测泛型类型参数,所以它returns一个Predicate<Object>
。
在一行中键入它的正确方法是指定类型参数,例如
Predicate<Integer> predicate = Predicate.<Integer>isEqual(0).or(Predicate.isEqual(1));
问题与推理在 Java 中的工作方式有关:它取决于目标。
这里:
Predicate<Integer> predicate = Predicate.isEqual(0)
.or(Predicate.isEqual(1));
由 or(Predicate.isEqual(1))
编辑的 return 类型取决于 Predicate.isEqual(0)
编辑的 return 类型(最近的目标),但此调用未指定任何其他类型作为 return.
所以 Object
是由 or(Predicate.isEqual(1))
编辑的,因为方法 isEqual()
将 T
定义为没有任何通配符的 return 类型:
static <T> Predicate<T> isEqual(Object targetRef) {
要解决您的问题,您确实需要指定第一次调用的 return 类型,以便链式调用能够推断出正确的类型:Integer
.
Predicate<Integer> predicate = Predicate.<Integer>isEqual(0)
.or(Predicate.isEqual(1));
这两种创建 lambda 的方式有什么区别?为什么第一个不编译?
Predicate<Integer> predicate = Predicate.isEqual(0).or(Predicate.isEqual(1));
给出:
错误:类型不兼容:Predicate<Object>
无法转换为 Predicate<Integer> = Predicate.isEqual(0).or(Predicate.isEqual(1));
Predicate<Integer> pred21 = Predicate.isEqual(0);
Predicate<Integer> pred22 = pred21.or(Predicate.isEqual(1));
这个有效。
在 isEqual
方法调用之前添加 <Integer>
应该会有所帮助:
Predicate<Integer> predicate = Predicate.<Integer>isEqual(0).or(Predicate.isEqual(1));
这种编译器行为背后的原因:
isEqual
是一个静态泛型方法,它 returnsPredicate<T>
(不管它的输入参数的实际类型是什么),所以它 returnsPredicate<Object>
在调用方法时未明确指定返回类型。or
也是一个静态泛型方法,但是它 returns 一个谓词参数化了相同的类型,作为它的输入参数(即Predicate<Object>
)。
发生这种情况是因为
Predicate.isEqual(0)
有这个签名:
static <T> Predicate<T> isEqual(Object targetRef)
如果您不输入它,它会推断 Predicate<Object>
。
要键入它,您可以键入 return 类型
Predicate<Integer> pred21 = Predicate.isEqual(0);
或像这样输入电话
Preicate.<Integer>isEqual
看签名:
static <T> Predicate<T> isEqual(Object targetRef)
在第一个例子中,编译器无法猜测泛型类型参数,所以它returns一个Predicate<Object>
。
在一行中键入它的正确方法是指定类型参数,例如
Predicate<Integer> predicate = Predicate.<Integer>isEqual(0).or(Predicate.isEqual(1));
问题与推理在 Java 中的工作方式有关:它取决于目标。
这里:
Predicate<Integer> predicate = Predicate.isEqual(0)
.or(Predicate.isEqual(1));
由 or(Predicate.isEqual(1))
编辑的 return 类型取决于 Predicate.isEqual(0)
编辑的 return 类型(最近的目标),但此调用未指定任何其他类型作为 return.
所以 Object
是由 or(Predicate.isEqual(1))
编辑的,因为方法 isEqual()
将 T
定义为没有任何通配符的 return 类型:
static <T> Predicate<T> isEqual(Object targetRef) {
要解决您的问题,您确实需要指定第一次调用的 return 类型,以便链式调用能够推断出正确的类型:Integer
.
Predicate<Integer> predicate = Predicate.<Integer>isEqual(0)
.or(Predicate.isEqual(1));