2

在 Java 中,我可以使用 ClassLoader 来获取已加载的类的列表以及这些类的包。但是我如何获得可以加载的类列表,即在类路径上?与包裹相同。

这是针对编译器的;在解析 foo.bar.Baz 时,我想知道 foo 是否是一个包以将其与其他任何内容区分开来。

4

3 回答 3

4

它有点棘手,有一些图书馆可以提供帮助,但基本上......

  1. 看看你的类路径
  2. 如果您正在处理一个目录,您可以查找所有以 .class 结尾的文件
  3. 如果您正在处理一个 jar,请加载该 jar 并查找所有以 .class 结尾的文件
  4. 从文件末尾删除.class,将“\”替换为“.” 然后你就有了完全限定的类名。

如果你的类路径中有 spring,你可以利用它们来完成大部分工作:

ArrayList<String> retval = new ArrayList<Class<?>>();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resolver);
String basePath = ClassUtils.convertClassNameToResourcePath("com.mypackage.to.search");
Resource[] resources;
try {
    resources = resolver.getResources("classpath*:" + basePath + "/**/*.class");
} catch (IOException e) {
    throw new AssertionError(e);
}
for (Resource resource : resources) {
    MetadataReader reader;
    try {
        reader = readerFactory.getMetadataReader(resource);
    } catch (IOException e) {
        throw new AssertionError(e);
    }
String className = reader.getClassMetadata().getClassName();
retval.add(className)   
}
return retval;
于 2009-08-21T15:46:33.320 回答
3

我认为org.reflections 库应该做你想做的事。它扫描类路径并允许您获取所有类或仅获取扩展特定超类型的类。从那里,应该可以获得所有可用的软件包。

于 2009-08-20T22:31:05.820 回答
2

我自己已经搜索过这个答案,但这是不可能的。

我知道的唯一方法是您拥有所有可以加载到特定目录中的类,然后在其中搜索以 .class 结尾的文件的名称。

之后,您可以Class.forName(name_of_class_file).createInstance()对这些文件名进行操作。

于 2009-08-20T22:18:46.250 回答