[英]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.