繁体   English   中英

Thinking lib for Java:查找包中的所有类

[英]Reflections lib for Java: find all classes in a package

继这里发布的问题: 你能用反射找到包中的所有类吗? 我开始使用Reflections库来查找子类给定类型的所有类。 从链接的SO问题的答案来看,源代码如下所示:

Reflections ref = new Reflections(new ConfigurationBuilder()
    .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
    .setUrls(ClasspathHelper.forPackage("org.somepackage"))
    .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("org.somepackage"))));

ref.getSubtypesOf(Object.class);

然而,在暂时使用这段代码之后,我刚刚发现它只会在这个包中找到继承其他类型的类。 它不会找到从外部定义的类子类化的类,比如来自另一个用户定义的类。

我不知道如何使用Reflections库来解决这个问题。 我希望所有将其包声明为'org.somepackage'的类,无论它们的超类型是什么。 有帮助吗?

我写了一个名为Rebound (而不是Reflection)的库,它搜索给定类型和包前缀的子类。 如果将前缀设置为空,它将搜索类路径下的每个类,例如

import gigadot.exp.reflects.core.Processor;

Rebound r = new Rebound("");
Set<Class<? extends Processor>> classes = r.getSubClassesOf(Processor.class);

但是你应该小心,因为在类路径中搜索所有内容是一个缓慢的过程。

该库比Reflection简单得多,可能无法满足您的需求。 我写这篇文章是因为我在提交错误报告时感到沮丧,但没有人试图解决问题。

原因是,那

ref.getSubtypesOf(Object.class);

只返回Object的直接子类。 如果要从扫描包中获取所有类,则应执行以下操作:

Reflections ref = new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner(false), new ResourcesScanner(), new TypeElementsScanner())
...
Set<String> typeSet = reflections.getStore().getStoreMap().get("TypeElementsScanner").keySet();
HashSet<Class<? extends Object>> classes = Sets.newHashSet(ReflectionUtils.forNames(typeSet, reflections
            .getConfiguration().getClassLoaders()));

这可能看起来有点hackish但是这是我到目前为止找到的唯一方法。 以下是对此操作的一点解释:当使用扫描完成反射时,它会将所有元素放在多值映射中。 在我粘贴的代码示例中,结果使用以下键放在地图中:

SubTypesScanner, ResourcesScanner, TypeElementsScanner

ResourceScanner排除以.class结尾的所有文件。 TypeElementsScanner是一个带有键的映射,其中包含类的名称和字段的值等。因此,如果您只想获取类名,则基本上可以获取键集,稍后将其转换为集合,如果类。 SubTypesScanner也是一个映射,具有所有超类(包括对象和接口)和值的键 - 实现/扩展这些接口/类的类。

如果您愿意,也可以通过迭代键集并获取所有值来使用SubTypesScanner,但如果某个类实现了接口,则必须处理重复的实体(因为每个类都扩展了Object)。

希望有所帮助。

在我的例子中,这个代码可以很好地加载外部API的类,但不知道为什么它不适用于像'java.util'这样的内置包。

Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
                .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[2])))
                .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("org.reflections"))));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM