【问题标题】:Get all classes which extend class inferring certain generics获取所有扩展类推断某些泛型的类
【发布时间】:2018-06-22 20:28:05
【问题描述】:

我正在寻找某种方法来获取扩展某个类并推断某些泛型的所有类。 我知道使用Reflections 我可以获得所有扩展类的类

final Reflections reflections = new Reflections("path.to.package");
Set<Class<? extends ClassBase>> classes = reflections.getSubTypesOf(ClassBase.class);

但我不确定如何只获得那些使用某些泛型的人。这是我想要实现的示例

假设我有ClassBase&lt;T&gt;

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 并推断 &lt;Long&gt; 的类的集合泛型类型。
或者更好的是,我实际上想要一个Set&lt;Class&lt;ClassBase&lt;Long&gt;&gt;&gt; 而不仅仅是一个Set&lt;Class&lt;ClassBase&gt;&gt;,它只包含那些推断Long 为通用的

【问题讨论】:

    标签: java generics


    【解决方案1】:

    您可以使用函数getGenericSuperclassgetActualTypeArguments 查看推断的泛型类型,这是一个示例:

    // 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&lt;Class&lt;? extends ClassBase&lt;Long&gt;&gt;&gt;,它包含扩展ClassBase&lt;Long&gt; 的类。您要求的 Set&lt;Class&lt;ClassBase&lt;Long&gt;&gt;&gt; 在技术上应该只拥有 ClassBase 本身的类,而您实际上对子类感兴趣,所以您会得到 Class&lt;? extends ClassBase&lt;Long&gt;&gt;

    【讨论】:

      【解决方案2】:

      对于使用 spring 并让这些类由容器管理的人(它们使用一些 spring 注释进行注释,例如 @Service@Component),您可以通过以下方法获取所有类:

      @Inject Set <ClassBase <Long>> extensionsWithLongType; 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-06
        • 1970-01-01
        • 2011-11-15
        • 1970-01-01
        • 2013-02-11
        • 1970-01-01
        相关资源
        最近更新 更多