Java中的泛型,返回一组泛型类Set <t>

时间:2018-11-28 09:21:17

标签: java class generics

所以我有这段代码,我试图返回一组扩展另一个类的类

public static <T> Set<T> getClassesExtending(Class<T> clazz) {
    Reflections reflections = new Reflections("");
    Set<Class<? extends T>> classes = reflections.getSubTypesOf(clazz);

    if (classes.size() <= 0) return new HashSet<>();

    Set<T> extending = classes.stream().filter(c -> c instanceof T).collect(Collectors.toSet());

    return extending;
}

问题:

c instanceof T //shows compile error 'Class or array expected' above 'T'

例如,如果我要写...

getClassesExtending(MyClass.class).forEach(c -> c.methodInMyClass())

它将起作用。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

  • 首先,按照您描述的方式使用它,
    • 找到扩展类clazz的类
    • 使用其默认构造函数创建其对象,然后
    • 对其调用方法。

此代码应该可以完成您的工作

public static <T> Set<? extends T> getClassesExtending(Class<T> clazz) {
        Reflections reflections = new Reflections("");
        Set<Class<? extends T>> classes = reflections.getSubTypesOf(clazz);

        if (classes.size() <= 0) return new HashSet<>();

        Set<? extends T> extending =
                classes.stream().map(aClass -> {
                    try {
                        return aClass.getConstructor().newInstance();
                    } catch (Exception e) {
                        return null;
                    }
                }).collect(Collectors.toSet());
         return extending;
    }    

我建议您进行一次filter()操作,以过滤掉没有no-arg构造函数的所有子类,以防止null集中的extending s。

  • 第二,当你这样做

    Set<T> extending = classes.stream().filter(c -> c instanceof T).collect(Collectors.toSet());

如果您实际上试图将集合过滤到类中,则该操作将是幂等的,也就是说,该集合不会产生任何变化。

最后,c instanceof T导致编译错误的原因是,instanceOf运算符不允许在其rhs上使用不可重新定义的类型,而通用类型也是不可重新定义的。 (JLS 11 section: 15.20.2

答案 1 :(得分:0)

这里的问题是T在运行时被删除了。

您可以尝试以下方法:

Set<T> extending = classes.stream().filter(c -> c.isAssignableFrom(clazz)).collect(Collectors.toSet());