2

I've been banging my head on the table over this for a few hours now.

I have this Map:
private static Map<Class<? extends BaseClass>, Predicate<? extends BaseClass>> constraints;

And I have this method:

public static <C extends BaseClass> Predicate<C> getConstraints(Class<? super C> clazz) {
    if (clazz == BaseClass.class) {
        return (Predicate<C>) constraints.getOrDefault(BaseClass.class, x -> true);
    }
    Class<? super C> superClass = clazz.getSuperclass();
    return constraints.getOrDefault(clazz, x -> true).and(getConstraints(superClass));
}

All this is supposed to do is to chain all constraints for a certain class (and the superclasses) in a Predicate<T> using the and() method. The generics seem logical to me but I still get an error when making the recursive call. getConstraints(Class<? super C>) cannot be applied to Class<capture of ? super E>. I don't get it because superClass is of the type Class<? super C> which is exactly the parameter that my method accepts. Any ideas?

0

1 Answer 1

2

You could use a type variable that represents the superclass:

@SuppressWarnings("unchecked")
public static <S extends BaseClass, C extends S> Predicate<C> getConstraints(Class<C> clazz) {
    if (clazz == BaseClass.class) {
        return (Predicate<C>) constraints.getOrDefault(BaseClass.class, x -> true);
    }
    Class<S> superClass = (Class<S>) clazz.getSuperclass();
    Predicate<C> p1 = (Predicate<C>) constraints.getOrDefault(clazz, x -> true);
    Predicate<S> p2 = getConstraints(superClass);
    return p1.and(p2);
}

You will also have to cast the result of getOrDefault, since putting the Predicate in the map 'forgets' the type information, and you get back a generic Predicate<? extends BaseClass>, which you can't use directly.

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thanks, that work's great. I've discovered the parameter C can be omitted. The parameter S is enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.