Почему 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
Другие вопросы по тегам