如何在Java中找到给定类的所有子类(或给定接口的所有实现者)? 到目前为止,我有一个方法来做到这一点,但我发现它相当低效(至少可以说)。 方法是:
获取类路径上存在的所有类名的列表 加载每个类并测试它是否是所需类或接口的子类或实现者
在Eclipse中,有一个很好的特性叫做类型层次结构,它能够非常有效地显示这一点。 如何以编程的方式进行呢?
如何在Java中找到给定类的所有子类(或给定接口的所有实现者)? 到目前为止,我有一个方法来做到这一点,但我发现它相当低效(至少可以说)。 方法是:
获取类路径上存在的所有类名的列表 加载每个类并测试它是否是所需类或接口的子类或实现者
在Eclipse中,有一个很好的特性叫做类型层次结构,它能够非常有效地显示这一点。 如何以编程的方式进行呢?
当前回答
不要忘记,为类生成的Javadoc将包括一个已知子类列表(对于接口,包括已知实现类)。
其他回答
用纯Java扫描类并不容易。
spring框架提供了一个名为ClassPathScanningCandidateComponentProvider的类,它可以满足您的需要。下面的示例将在包org.example.package中找到MyClass的所有子类
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(MyClass.class));
// scan in org.example.package
Set<BeanDefinition> components = provider.findCandidateComponents("org/example/package");
for (BeanDefinition component : components)
{
Class cls = Class.forName(component.getBeanClassName());
// use class cls found
}
该方法还有一个额外的好处,就是使用字节码分析器来查找候选类,这意味着它不会加载所扫描的所有类。
如果你想加载给定类在同一个包中的所有子类,你可以这样做:
public static List<Class> loadAllSubClasses(Class pClazz) throws IOException, ClassNotFoundException {
ClassLoader classLoader = pClazz.getClassLoader();
assert classLoader != null;
String packageName = pClazz.getPackage().getName();
String dirPath = packageName.replace(".", "/");
Enumeration<URL> srcList = classLoader.getResources(dirPath);
List<Class> subClassList = new ArrayList<>();
while (srcList.hasMoreElements()) {
File dirFile = new File(srcList.nextElement().getFile());
File[] files = dirFile.listFiles();
if (files != null) {
for (File file : files) {
String subClassName = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
if (! subClassName.equals(pClazz.getName())) {
subClassList.add(Class.forName(subClassName));
}
}
}
}
return subClassList;
}
我使用了一个反射库,它扫描所有子类的类路径:https://github.com/ronmamo/reflections
这是如何做到的:
Reflections reflections = new Reflections("my.project");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
我只是写了一个简单的演示来使用org.reflections.Reflections来获取抽象类的子类:
https://github.com/xmeng1/ReflectionsDemo
仅使用内置的Java Reflections API是不可能做到这一点的。
存在一个项目,它对你的类路径进行必要的扫描和索引,这样你就可以访问这些信息……
反射
Java运行时元数据分析,遵循Scannotations的精神 Reflections扫描您的类路径,索引元数据,允许您在运行时查询它,并可以为项目中的许多模块保存和收集这些信息。 使用Reflections你可以查询你的元数据: 获取某个类型的所有子类型 用一些注释来注释所有类型 获取使用某些注释注释的所有类型,包括注释参数匹配 让所有方法都带有一些注解
(免责声明:我没有使用过它,但项目的描述似乎完全符合您的需求。)