获取所有扩展类以推断某些泛型的类

时间:2018-06-22 11:45:43

标签: java generics

我正在寻找一种方法来获取扩展某个类并推断某些泛型的所有类。 我知道使用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> {}

我如何只获得ClassAClassB?我什至可以接受所有扩展ClassBase的类,然后过滤掉不需要的类,只要我最终得到的集合只包含那些扩展ClassBase并推断出的类<Long>作为通用类型。
或者更好的是,我实际上希望一个Set<Class<ClassBase<Long>>>而不只是一个Set<Class<ClassBase>>,其中仅包含那些推断Long为通用的

2 个答案:

答案 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;