谓词<? super X>.and(Predicate<? super X>) 不适用于参数 Predicate<?超X>
Predicate<? super X>.and(Predicate<? super X>) is not applicable for the argument Predicate<? super X>
我必须对实现 Predicate<MoneyOperation>
的业务对象执行 and()
。
出现问题的代码是 and()
调用的行:
Predicate<? super MoneyOperation> predicate =
new MoneyOperationDateWithRadioButtonsPredicate(newv,
thisDayRdBtn.getValue(), date);
filteredData.setPredicate(filteredData.getPredicate().and(predicate));
错误:
The method and(Predicate<? super capture#14-of ? super MoneyOperation>)
in the type Predicate<capture#14-of ? super MoneyOperation> is not applicable
for the arguments (Predicate<capture#15-of ? super MoneyOperation>)
虽然当我将 predicate
传递给 setPredicate()
而不调用 and()
编译器不会引发任何错误。
MoneyOperationDateWithRadioButtonsPredicate
class:
public class MoneyOperationDateWithRadioButtonsPredicate extends MoneyOperationFieldPredicate<LocalDate> { ... }
MoneyOperationFieldPredicate
class:
public abstract class MoneyOperationFieldPredicate<T> implements Predicate<MoneyOperation> { ... }
这只是类型系统的限制,因为 Java 没有使用 Predicate
没有生产者方法(在 PECS 的意义上)这一事实来处理输入不同。
考虑两个 List<? super Integer>
实例:你不能做 list1.addAll(list2)
,原因与你不能在这里做 predicate1.and(predicate2)
的原因相同:这是为了防止 list1
可能是 List<Integer>
,而 list2
是 List<Object>
:您不应将对象添加到您希望只包含整数的列表中。
这是 List
的一个实际问题,因为 List
有生产者方法(例如 List.get(int)
),即旨在为您提供特定类型实例的方法。 Predicate
只有消费者方法(一个,准确地说,Predicate.test<T>
),所以不会有 Predicate
给你一个意外类型的对象的情况。
但是,编译器不考虑 class 是否没有生产者方法(或没有消费者方法):它假设两者都存在(实际上,它们可能存在于 subclasses ), 所以它会阻止你这样做。也许很烦人,但事实就是如此。
最简单的方法是构造一个 lambda 来显式测试两个谓词:
setPredicate(a -> predicate1.test(a) && predicate2.test(b))
你也许可以使用这个奇怪的技巧:
setPredicate(Stream.of(predicate1, predicate2).map(a -> a).reduce(Predicate::and))
但无论是按规范还是按怪癖实施,我都不太满意。
这里的问题是捕获。让我们看看这些限制意味着什么:
Predicate<? super MoneyOperation>
是一个谓词,可以采用 MoneyOperation
或者它可能是超级 class 和 returns 布尔值。
这意味着它可以是一个 Predicate<Object>
接受一个 Object
和 returns 一个布尔值。
现在有一个潜在的问题:
假设 MoneyOperation
扩展了 GenericOperation
并实现了 SomeInterface
.
第一个 Predicate<? super MoneyOperation>
实际上可能是 Predicate<GenericOperation>
,第二个 Predicate<? super MoneyOperation>
可能是 Predicate<SomeInterface>
。 (Java 编译器无法判断)
将 MoneyOperation
传递给它们两者都很好,但将它们组合起来需要将其类型限制为 Predicate<MoneyOperation>
。虽然这对 Predicate
没问题,但可能不适用于其他情况。
这就是 Java 不允许这样做的原因。
如果您知道它是一个,请使用 Predicate<MoneyOperation>
。
我必须对实现 Predicate<MoneyOperation>
的业务对象执行 and()
。
出现问题的代码是 and()
调用的行:
Predicate<? super MoneyOperation> predicate =
new MoneyOperationDateWithRadioButtonsPredicate(newv,
thisDayRdBtn.getValue(), date);
filteredData.setPredicate(filteredData.getPredicate().and(predicate));
错误:
The method and(Predicate<? super capture#14-of ? super MoneyOperation>)
in the type Predicate<capture#14-of ? super MoneyOperation> is not applicable
for the arguments (Predicate<capture#15-of ? super MoneyOperation>)
虽然当我将 predicate
传递给 setPredicate()
而不调用 and()
编译器不会引发任何错误。
MoneyOperationDateWithRadioButtonsPredicate
class:
public class MoneyOperationDateWithRadioButtonsPredicate extends MoneyOperationFieldPredicate<LocalDate> { ... }
MoneyOperationFieldPredicate
class:
public abstract class MoneyOperationFieldPredicate<T> implements Predicate<MoneyOperation> { ... }
这只是类型系统的限制,因为 Java 没有使用 Predicate
没有生产者方法(在 PECS 的意义上)这一事实来处理输入不同。
考虑两个 List<? super Integer>
实例:你不能做 list1.addAll(list2)
,原因与你不能在这里做 predicate1.and(predicate2)
的原因相同:这是为了防止 list1
可能是 List<Integer>
,而 list2
是 List<Object>
:您不应将对象添加到您希望只包含整数的列表中。
这是 List
的一个实际问题,因为 List
有生产者方法(例如 List.get(int)
),即旨在为您提供特定类型实例的方法。 Predicate
只有消费者方法(一个,准确地说,Predicate.test<T>
),所以不会有 Predicate
给你一个意外类型的对象的情况。
但是,编译器不考虑 class 是否没有生产者方法(或没有消费者方法):它假设两者都存在(实际上,它们可能存在于 subclasses ), 所以它会阻止你这样做。也许很烦人,但事实就是如此。
最简单的方法是构造一个 lambda 来显式测试两个谓词:
setPredicate(a -> predicate1.test(a) && predicate2.test(b))
你也许可以使用这个奇怪的技巧:
setPredicate(Stream.of(predicate1, predicate2).map(a -> a).reduce(Predicate::and))
但无论是按规范还是按怪癖实施,我都不太满意。
这里的问题是捕获。让我们看看这些限制意味着什么:
Predicate<? super MoneyOperation>
是一个谓词,可以采用 MoneyOperation
或者它可能是超级 class 和 returns 布尔值。
这意味着它可以是一个 Predicate<Object>
接受一个 Object
和 returns 一个布尔值。
现在有一个潜在的问题:
假设 MoneyOperation
扩展了 GenericOperation
并实现了 SomeInterface
.
第一个 Predicate<? super MoneyOperation>
实际上可能是 Predicate<GenericOperation>
,第二个 Predicate<? super MoneyOperation>
可能是 Predicate<SomeInterface>
。 (Java 编译器无法判断)
将 MoneyOperation
传递给它们两者都很好,但将它们组合起来需要将其类型限制为 Predicate<MoneyOperation>
。虽然这对 Predicate
没问题,但可能不适用于其他情况。
这就是 Java 不允许这样做的原因。
如果您知道它是一个,请使用 Predicate<MoneyOperation>
。