所以我有这个代码,我试图返回一组正在扩展另一个类的类
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())
它会起作用的。有什么建议吗?
- 首先,根据您所描述的使用方式,您需要
- 查找扩展类
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()
操作来过滤掉任何没有无arg构造函数的子类,以防止extending
集中出现null
。
其次,当你做这个时
Set<T> extending = classes.stream().filter(c -> c instanceof T).collect(Collectors.toSet());
如果你真的试图将集合过滤成类,那么这个操作将是幂等的,也就是说,它不会在集合中产生任何变化。
最后,c instanceof T
导致编译错误的原因是,instanceOf
运算符不允许在其rhs上使用不可重写类型,并且泛型类型是不可重写的。(JLS 11节:15.20.2(
这里的问题是T
在运行时被擦除。
你可以试试这个:
Set<T> extending = classes.stream().filter(c -> c.isAssignableFrom(clazz)).collect(Collectors.toSet());