【问题标题】:Why doesn't reflections.getSubTypesOf(Object.class) find enums?为什么反射.getSubTypesOf(Object.class) 找不到枚举?
【发布时间】:2016-02-23 18:07:15
【问题描述】:

如果我有

Reflections reflections = new Reflections("my.package", classLoader, new SubTypesScanner(false));

然后这会找到我的枚举类

Set<Class<? extends Enum>> enums = reflections.getSubTypesOf(Enum.class);

但这不是

Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);

这是有原因的吗?


可重现的例子:

package cupawntae;

import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;

public class Reflector {
    public static void main(String[] args) {
        Reflections reflections = new Reflections("cupawntae", Reflector.class.getClassLoader(), new SubTypesScanner(false));
        System.out.println("Objects: " + reflections.getSubTypesOf(Object.class));
        System.out.println("Enums: " + reflections.getSubTypesOf(Enum.class));
        System.out.println("Enum's superclass: " + Enum.class.getSuperclass());
    }
}

枚举类:

package cupawntae;

public enum MyEnum {
}

输出:

Objects: [class cupawntae.Reflector]
Enums: [class cupawntae.MyEnum]
Enum's superclass: class java.lang.Object

【问题讨论】:

  • 看起来像一个错误。请注意,如果枚举实现了任何接口,它会突然被发现。在错误得到修复之前,您可以使用例如ClassPath.from(ClassLoader.getSystemClassLoader()).getTopLevelClasses("cupawntae") Google Guava。不是那么光滑,但可以完成工作。
  • 谢谢,但看起来它已记录在案 - 尽管界面的东西很奇怪。你是怎么发现的?您是否有机会在目标包中实现接口?

标签: java reflection enums reflections


【解决方案1】:

这实际上是documented behaviour,尽管它可能不是特别清晰或直观:

请注意,使用构造函数new Reflections("my.package")时,只会扫描带有前缀'my.package'的url,而不会扫描其他url中的任何传递类(例如,如果my.package.SomeClass扩展other.package.OtherClass,比后者不会被扫描)。在这种情况下,使用其他构造函数并指定相关的包/url

编辑:该文档的later revision 说:

确保扫描所有传递相关的包。 例如,假设您的类 C 扩展 B 扩展 A,并且 B 和 A 都位于 C 以外的另一个包中,当仅扫描 C 的包时 - 然后查询 A 的子类型不返回任何内容(传递),但查询B 的子类型返回 C(直接)。在这种情况下,请务必先扫描所有相关包。

在这种情况下,java.lang.Enum 算作传递类(如 other.package.OtherClass),因此不包括在扫描中,这意味着不包括 Enum 的子类。

同样,如果我们在问题示例中将Reflections 扩展为目标包之外的内容,例如

public class Reflector extends Exception {

然后在扫描中找不到该类

Objects: []
Enums: [class cupawntae.MyEnum]
Enum's superclass: class java.lang.Object

【讨论】:

  • 哇,太糟糕了。因此,如果您有一个扩展AbstractList 的专用类,或者您自己的异常,如您所展示的,那么reflections.getAllTypes() 将找不到它。真是一团糟。即使这是有意的,也应该以某种方式进行更改。至少它应该自动遍历 java.lang 和 java.util!
  • 天哪。即使您专门将java.langjava.util 作为包包含在内,reflections.getAllTypes()reflections.getSubTypesOf(Object.class) 都不会为您提供专门的异常/列表。所以没有办法用这个库来获取你所有的类,是吗?真可惜。
  • 好的,最后的评论,我会完成的。除了已经提到的 Guava 的 ClassPath,还有 github.com/lukehutch/fast-classpath-scanner 也可以做到这一点。我没试过,但看起来很成熟。
  • 明天还要再看看这些东西 - 感谢您的指点,如果我发现其他有用的东西我会更新
  • 胡安·加西亚,如果你看到这个,谢谢你的编辑。实际上,您发现的那个更新,并且被稍微改写了(不确定它是否反映了(不是双关语)行为的变化,没有足够详细地阅读)。无论如何,我只是尝试将10 更改为9,因为它可能会找到我引用的版本,你知道什么?在那里!干杯
猜你喜欢
  • 1970-01-01
  • 2016-07-13
  • 2013-01-16
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
相关资源
最近更新 更多