我必须对实现Predicate<MoneyOperation>的业务对象执行Predicate<MoneyOperation>。
出现问题的代码是使用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类:
public class MoneyOperationDateWithRadioButtonsPredicate extends MoneyOperationFieldPredicate<LocalDate> { ... }MoneyOperationFieldPredicate类:
public abstract class MoneyOperationFieldPredicate<T> implements Predicate<MoneyOperation> { ... }发布于 2019-08-25 20:53:02
这只是类型系统的一个限制,因为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会给出意外类型的对象的情况。
但是,编译器不考虑类是否没有生产者方法(或者没有使用者方法):它假设两个方法都存在(实际上,它们可能存在于子类中),因此它阻止了您这样做。也许很烦人,但事情就是这样。
最简单的方法是构造一个lambda来显式测试这两个谓词:
setPredicate(a -> predicate1.test(a) && predicate2.test(b))你也许可以用这个诡计:
setPredicate(Stream.of(predicate1, predicate2).map(a -> a).reduce(Predicate::and))但是,无论是通过规范,还是通过奇怪的实现,我都不太满意。
发布于 2019-08-25 21:00:21
这里的问题是捕获。让我们看看这些约束意味着什么:
Predicate<? super MoneyOperation>是一个谓词,可以接受MoneyOperation,也可能是超类,并返回布尔值。这意味着它可以是一个接受Predicate<Object>并返回布尔值的Object。
现在有一个潜在的问题:
让我们假设MoneyOperation扩展了GenericOperation并实现了SomeInterface。
实际上,第一个Predicate<? super MoneyOperation>可能是Predicate<GenericOperation>,第二个Predicate<? super MoneyOperation>是Predicate<SomeInterface>。( Java编译器无法分辨)将MoneyOperation传递给两者都很好,但是将它们组合在一起将需要将其类型限制为Predicate<MoneyOperation>。虽然这对于Predicate来说是可以的,但对于其他情况则可能不适用。
这就是为什么Java不允许这样做。
如果你知道Predicate<MoneyOperation>是一个,就使用它。
https://stackoverflow.com/questions/57649578
复制相似问题