Подтвердить что ты не робот

Java Reflection - Получить список пакетов

Я создаю приложение Java, которое имеет несколько разных пакетов. Я хочу иметь возможность сказать программно, какие пакеты существуют в приложении, которые начинаются с определенного предварительного исправления. Есть ли все-таки сделать это с API-интерфейсами Java отражения? Я не видел ничего подобного, связанного с отражением apis.

Пример:

com.app.controls.text
com.app.controls.picker
com.app.controls.date
etc

Я хочу перечислить все это, зная префикс "com.app.controls" и понимая, что новый пакет может быть интегрирован в будущем.

Спасибо!

4b9b3361

Ответ 1

Вы можете сделать это, используя Package.getPackages(), который возвращает массив всех пакетов, известных текущему загрузчику класса. Вам придется вручную прокручивать массив и находить те, у которых есть соответствующий префикс, используя getName().

Вот пример:

public List<String> findPackageNamesStartingWith(String prefix) {
    List<String> result = new ArrayList<>();
    for(Package p : Package.getPackages()) {
        if (p.getName().startsWith(prefix)) {
           result.add(p.getName());
        }
    }
    return result;
}

Обратите внимание, что этот метод возвращает только пакеты, определенные в текущем загрузчике классов. Если вам нужны пакеты из другого загрузчика классов, есть несколько вариантов:

  • Расположите вещи так, чтобы ваша программа могла запускать вышеуказанный код внутри этого загрузчика классов. Это требует определенной организации для вашей базы кода, которая может быть или не быть осуществимой.

  • Используйте отражение, чтобы вызвать метод getPackages() в соответствующем загрузчике классов. Это не будет работать, если программа работает под управлением безопасности.

Ответ 2

Пакеты практически не существуют из POV отражения, они довольно невидимы, за исключением загрузчиков классов.

Ответ 3

Основываясь на Ответ Шона и используя отражение, чтобы получить список пакетов - возможно, игнорируя пустые:

/**
 * Finds all package names starting with prefix
 * @return Set of package names
 */
public Set<String> findAllPackagesStartingWith(String prefix) {
    List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
    classLoadersList.add(ClasspathHelper.contextClassLoader());
    classLoadersList.add(ClasspathHelper.staticClassLoader());
    Reflections reflections = new Reflections(new ConfigurationBuilder()
            .setScanners(new SubTypesScanner(false), new ResourcesScanner())
            .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
            .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("my.base.package"))));
    Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class);

    Set<String> packageNameSet = new TreeSet<String>();
    for (Class classInstance : classes) {
        String packageName = classInstance.getPackage().getName();
        if (packageName.startsWith(prefix)) {
            packageNameSet.add(packageName);
        }
    }
    return packageNameSet;
}