Reputation: 175
What I basically want is, that the more specialized type is inferred like in the following example:
Predicate<Object> first;
Predicate<String> second;
Predicate<String> firstOr = first.or(second);
Predicate<String> secondOr = second.or(first);
How would the method signature of or(...)
look like to accomplish this?
Upvotes: 3
Views: 92
Reputation: 28183
This can be accomplished with the following declaration of Predicate<T>::or
:
default <R extends T> Predicate<R> or(Predicate<? super R> other) {
return r -> this.test(r) || other.test(r);
}
This would allow or
to create a Predicate
for any subtype of both Predicate
types. So, for example, the following would work:
Predicate<Object> first;
Predicate<Number> second;
Predicate<Integer> firstOr = first.or(second);
Predicate<Integer> secondOr = second.or(first);
Upvotes: 4
Reputation: 28066
I think you need two overloads for this to work. However, because the only difference between the overloads is in the type parameters, they would clash because of erasure. You therefore need to name them differently (which would not make them actual overloads anymore).
This could be the signatures:
/* In this case, the input Predicate has the most specific type.
* Use this in the first.or(second) case
*/
public <R extends T> Predicate<R> or1(Predicate<R> pred);
/* In this case, the receiver Predicate has the most specific type.
* Use this in the second.or(first) case
*/
public Predicate<T> or2(Predicate<? super T> pred);
Both methods would work the same if the type parameters are equal (for example if both first
and second
had the type Predicate<String>
)
Upvotes: 2