Reputation: 2130
I'm having trouble using Java Predicates.
I have an enum:
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;
}
}
Now within a member of the class SacmElement
I try to do the test:
if (ValidationErrors.INCONSISTENT_IS_CITATION_ERROR.getIsValid().test(this))
That doesn't compile because "The method test(capture#1-of ? extends SacmElement) in the type Predicate is not applicable for the arguments (SacmElement).
I don't understand the error: I thought that for the purposes of Java generics a class is considered to extend itself. What am I doing wrong?
Upvotes: 3
Views: 986
Reputation: 361605
A good rule of thumb to remember is PECS: Producer Extends, Consumer Super. A predicate is a consumer, so it should use super
. Use Predicate<? super SacmElement>
instead of Predicate<? extends SacmElement>
.
With super
, you could have a predicate that checks SacmElement
s, or you could have one that's even more generic and checks any old Object
. A Predicate<Object>
would work here, wouldn't it?
With extends
, you may have yourself a predicate that can only handle some specific sub-class of SacmElement
rather than all SacmElement
s. That's no good. What if you're trying to test a regular SacmElement
but the predicate only accepts SpecificSacmElement
s?
Upvotes: 3