反映子类的Java

时间:2010-02-26 10:31:32

标签: java reflection

我有一个Java类,我想反映这个类的所有子类,我该怎么做?

在这种特定情况下,所有子类都在同一个包中,并且只有子类在这个包中,因此一个等效的解决方案是获取包中的所有类。

3 个答案:

答案 0 :(得分:2)

我认为你可以使用spring org.springframework.core.io.support.PathMatchingResourcePatternResolver来做到这一点。至少我知道你可以使用它来查找具有特定注释的所有类。寻找子类似乎是一个非常类似的问题,我期望它也可以工作。

这里有一些(未经测试的)代码可以帮助您入门:

PathMatchingResourcePatternResolver match = new PathMatchingResourcePatternResolver();
MetadataReaderFactory f = new SimpleMetadataReaderFactory();
List<Class<?>> matches = ...;
for (Resource r : match.getResources("classpath*:com/example/**/*.class")) {
    AnnotationMetadata meta = f.getMetadataReader(r).getAnnotationMetadata();
    if (meta.getAnnotationsTypes().contains(MyAnnotation.class.getName()) {
        matches.add(Class.forName(meta.getClassName()));
    }
}
return matches;

正如您可能看到的,它基本上是由Stephen C

描述的想法

答案 1 :(得分:1)

请参阅this answer如何找到包中的所有类。

接下来,您将需要一个包含所有包的列表,这些包在一般情况下并非无足轻重。但是如果您只使用标准类加载器(它只依赖于类路径),您可以获取系统属性java.class.path并分析它以获取所有JAR。打开它们列出内容,然后你就会知道类名。

答案 2 :(得分:1)

在某些情况下可以做(混乱);例如如果您的应用程序的类是从本地目录或JAR文件加载的。基本上,您需要将包名称映射到路径名,并使用File和/或ZipFile API查找名称以“.class”结尾的相关“目录”中的文件。然后使用Class.forName()加载相应的类(试图避免初始化它们),并使用clazz.isAssignableFrom(subclazz)查看哪些是子类。

但这并不适用于所有情况。一个问题是ClassLoader API不支持迭代它可以加载的所有类/包。

我建议您找到解决问题的另一种方法。

编辑 - 回应此评论。

  

这似乎是java反射API中的一个大错误

我理解遗漏是故意的。如果类加载器API 包含一个方法来给出包中的所有类,它将限制可用于类加载的方案。例如,URLClassLoader不能为'http:'URL实现,因为HTTP协议不提供检索目录中条目的标准方法。

此外,很少有生产应用程序真正需要反映查找包中的所有类的情况。