我正在寻找一种方法来获取扩展某个类并推断某些泛型的所有类。
我知道使用Reflections
可以获取扩展一个类的所有类
final Reflections reflections = new Reflections("path.to.package");
Set<Class<? extends ClassBase>> classes = reflections.getSubTypesOf(ClassBase.class);
但是我不确定如何只使用某些泛型。这是我要实现的目标的一个例子
假设我有ClassBase<T>
public class ClassBase<T> {}
然后我有ClassA ClassB ClassC
,他们全都扩展了ClassBase
public class ClassA extends ClassBase<Long> {}
public class ClassB extends ClassBase<Long> {}
public class ClassC extends ClassBase<Integer> {}
我如何只获得ClassA
和ClassB
?我什至可以接受所有扩展ClassBase
的类,然后过滤掉不需要的类,只要我最终得到的集合只包含那些扩展ClassBase
并推断出的类<Long>
作为通用类型。
或者更好的是,我实际上希望一个Set<Class<ClassBase<Long>>>
而不只是一个Set<Class<ClassBase>>
,其中仅包含那些推断Long
为通用的
答案 0 :(得分:2)
您可以先使用getGenericSuperclass
函数,再使用getActualTypeArguments
函数来查看推断的泛型类型,这是一个示例:
// Given that all classes in this set are actually subclasses of ClassBase
Set<Class<? extends ClassBase>> classes = Set.of(ClassA.class, ClassB.class, ClassC.class);
System.out.println(classes); // [class test.ClassB, class test.ClassA, class test.ClassC]
@SuppressWarnings("unchecked")
Set<Class<? extends ClassBase<Long>>> result = classes.stream()
.filter(cls -> {
// Get superclass, which is ClassBase, so assume it's also parameterized
ParameterizedType superClass = (ParameterizedType) cls.getGenericSuperclass();
Type inferred = superClass.getActualTypeArguments()[0]; // get first type argument
return inferred == Long.class; // check if it's 'Long'
})
// Can now say they all extend ClassBase<Long>
.map(cls -> (Class<? extends ClassBase<Long>>) cls)
.collect(Collectors.toSet());
System.out.println(result); // [class test.ClassA, class test.ClassB]
您将获得一个Set<Class<? extends ClassBase<Long>>>
,其中包含扩展ClassBase<Long>
的类。您所要求的Set<Class<ClassBase<Long>>>
仅应从技术上讲属于类ClassBase
本身,而您实际上对子类感兴趣,因此您得到Class<? extends ClassBase<Long>>
。
答案 1 :(得分:0)
对于使用spring并由容器管理这些类的人(它们使用诸如@Service
,@Component
之类的spring注释进行注释),您可以使用以下方法获取所有类:>
@Inject Set <ClassBase <Long>> extensionsWithLongType;