14

さまざまなパッケージを持つJavaアプリを構築しています。特定のプレフィックスで始まるパッケージがアプリに存在するかどうかをプログラムで伝えたいです。JavaリフレクションAPIでこれを行う方法はありますか?リフレクションAPIに関連するこのようなものは見当たりませんでした。

例:

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

プレフィックス「com.app.controls」を知り、新しいパッケージが将来統合される可能性があることを理解して、これらすべてを列挙したいと思います。

ありがとう!

4

2 に答える 2

22

これを行うには、 Package.getPackages()を使用します。これにより、現在のクラスローダーに認識されているすべてのパッケージの配列が返されます。配列を手動でループし、 getName()を使用して適切なプレフィックスを持つ配列を見つける必要があります。

簡単な例を次に示します。

public List<String> findPackageNamesStartingWith(String prefix) {
    return Package.getPackages().stream()
        .map(Package::getName)
        .filter(n -> n.startsWith(prefix))
        .collect(toList());
}

この手法では、現在のクラスローダーで定義されているパッケージのみが返されることに注意してください。別のクラスローダーのパッケージが必要な場合は、いくつかのオプションがあります。

  1. プログラムがそのクラスローダー内から上記のコードを実行できるように調整します。これには、コードベースに特定の組織が必要ですが、実行可能かどうかは不明です。

  2. リフレクションを使用して、適切なクラスローダーで(通常は保護されている)メソッドgetPackages()を呼び出します。プログラムがセキュリティマネージャの下で実行されている場合、これは機能しません。

于 2012-12-19T02:25:46.490 に答える
-1

ショーンの答えに基づいて、リフレクションを使用してパッケージのリストを取得します-空のパッケージを無視する可能性があります:

/**
 * 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;
}
于 2014-01-27T12:41:31.960 に答える