递归方法中的泛型

时间:2018-09-23 12:16:24

标签: java generics recursion nested-generics

我已经在桌子上敲了几个小时。

我有此地图:
private static Map<Class<? extends BaseClass>, Predicate<? extends BaseClass>> constraints;

我有这个方法:

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));
}

这一切应该做的是使用Predicate<T>方法将and()中某个类(和超类)的所有约束链接起来。 在我看来,泛型似乎是合乎逻辑的,但是在进行递归调用时仍然出现错误。 getConstraints(Class<? super C>) cannot be applied to Class<capture of ? super E>。我不明白,因为superClass的类型为Class<? super C>,这正是我的方法接受的参数。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您可以使用代表超类的类型变量:

@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);
}

您还必须强制转换getOrDefault的结果,因为将Predicate放入地图中会“忘记”类型信息,并且您将获得通用的Predicate<? extends BaseClass>不能直接使用。