Почему reflections.getSubTypesOf(Object.class) не находит перечисления?
Если у меня есть
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());
}
}
Enum класс:
package cupawntae;
public enum MyEnum {
}
Выход:
Objects: [class cupawntae.Reflector]
Enums: [class cupawntae.MyEnum]
Enum's superclass: class java.lang.Object
1 ответ
Это на самом деле документированное поведение, хотя, возможно, оно не особенно понятно или интуитивно понятно:
знать, что при использовании конструктора
new Reflections("my.package")
, только URL с префиксом 'my.package
будет сканироваться, и любые переходные классы в других URL не будут сканироваться (например, если my.package.SomeClass расширяетсяother.package.OtherClass
, чем позже не будет отсканировано). в этом случае используйте другие конструкторы и укажите соответствующие пакеты / URL
редактировать: более поздняя версия этого документа говорит:
Обязательно просмотрите все транзитивно релевантные пакеты. например, если ваш класс 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