我有一个Java类,我想反映这个类的所有子类,我该怎么做?
在这种特定情况下,所有子类都在同一个包中,并且只有子类在这个包中,因此一个等效的解决方案是获取包中的所有类。
答案 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协议不提供检索目录中条目的标准方法。
此外,很少有生产应用程序真正需要反映查找包中的所有类的情况。