代码之家  ›  专栏  ›  技术社区  ›  valepu

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

  •  1
  • valepu  · 技术社区  · 8 年前

    我正在寻找一些方法来获取所有扩展某个类并推断某些泛型的类。 我知道使用 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 ?我甚至可以让所有的课程 阶级基础 然后过滤掉那些我不需要的,只要我得到一个只包含那些扩展类的集合 阶级基础 推断 <Long> 作为泛型类型。
    或者更好,我真的想 Set<Class<ClassBase<Long>>> 不只是一个 Set<Class<ClassBase>> 只包含那些推断 Long 作为通用

    2 回复  |  直到 8 年前
        1
  •  2
  •   Jorn Vernee    8 年前

    可以使用函数查看推断泛型类型。 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>> .

        2
  •  0
  •   NiVeR    8 年前

    对于使用Spring的人,并使用容器管理的类(用弹簧注释注释) @Service , @Component ),您可以使用以下方法获取所有类:

    @Inject Set <ClassBase <Long>> extensionsWithLongType;