传递Java谓词

时间:2018-07-02 02:28:31

标签: java

我在使用Java谓词时遇到麻烦。

我有一个枚举:

public enum ValidationErrors {
    INCONSISTENT_IS_CITATION_ERROR((SacmElement element)->{
        return !element.getCitedElement().isPresent() || element.getIsCitation();} );

    private final Predicate<? extends SacmElement> isValid;

    ValidationErrors(Predicate<? extends SacmElement> isValid) {
        this.isValid = isValid;
    }

    public Predicate<? extends SacmElement> getIsValid() {
        return isValid;
    }
}

现在在类SacmElement的成员中,我尝试进行测试:

if (ValidationErrors.INCONSISTENT_IS_CITATION_ERROR.getIsValid().test(this))

之所以不能编译,是因为“谓词类型中的方法test(capture#1-of扩展了SacmElement)不适用于参数(SacmElement)。

我不明白该错误:我认为出于Java泛型的目的,一个类被认为是自身的扩展。我在做什么错了?

1 个答案:

答案 0 :(得分:3)

要记住的一个很好的经验法则是PECS:Producer Extends, Consumer Super。谓词是使用者,因此应使用super。使用Predicate<? super SacmElement>代替Predicate<? extends SacmElement>

使用super,您可以有一个检查SacmElement的谓词,也可以有一个更通用的谓词并检查任何旧的ObjectPredicate<Object>可以在这里工作,不是吗?

使用extends,您可能拥有一个只能处理SacmElement某些特定子类而不是所有SacmElement的谓词。不好如果您要测试常规SacmElement但谓词仅接受SpecificSacmElement,该怎么办?