对于这里发布的问题:Can you find all classes in a package using reflection?,我开始使用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',而不管它们的超类型是什么。有什么帮助吗?
发布于 2012-09-20 00:44:14
我编写了一个名为Rebound的库(与反射相反),它可以搜索给定类型和包前缀的子类。如果将前缀设置为空,它将搜索类路径下的每个类,例如
import gigadot.exp.reflects.core.Processor;
Rebound r = new Rebound("");
Set<Class<? extends Processor>> classes = r.getSubClassesOf(Processor.class);但您应该小心,因为搜索类路径中的所有内容是一个缓慢的过程。
该库比Reflections简单得多,可能不会执行您想要的操作。我写这篇文章是因为我提交了我的bug报告,但是没有人试图解决这个问题。
发布于 2013-11-04 23:51:41
这样做的原因是
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()));这可能看起来有点老土,但这是我到目前为止发现的唯一方法。这里有一点关于它的用途的解释:当Reflections完成扫描时,它将所有元素放在一个多值映射中。在我粘贴的代码示例中,结果被放入具有以下键的map中:
SubTypesScanner, ResourcesScanner, TypeElementsScannerResourceScanner将排除所有以.class结尾的文件。TypeElementsScanner是一个映射,其中包含一个包含类名称的键和一个字段的值等。因此,如果您只想获取类名,那么基本上就是获取键集,然后将其转换为一个集合。SubTypesScanner也是一个映射,具有所有超类(包括对象和接口)和值的键-实现/扩展这些接口/类的类。
如果愿意,您也可以使用SubTypesScanner,通过迭代键集并获取所有值,但是如果某个类实现了一个接口,您将不得不处理重复的实体(因为每个类都扩展Object)。
希望这能有所帮助。
发布于 2013-03-13 20:21:01
在我的例子中,这段代码可以很好地加载外部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"))));https://stackoverflow.com/questions/12498714
复制相似问题