15

Java コードベースに「com.example」というパッケージがあるとします。

実行時に、呼び出してこのパッケージを取得できます。

Package p = Package.getPackage( "com.example" ); //(returns null)

または、呼び出してすべてのパッケージのリストを取得することもできます

Packages[] ps = Package.getPackages();

問題は、ClassLoader がパッケージからクラスをまだロードしていない場合、これらの関数呼び出しで使用できないことです。次のように、最初にパッケージ内のクラスの 1 つを強制的にロードすることで、パッケージを強制的にロードすることができます。

this.getClass().getClassLoader().loadClass( "com.example.SomeClass" );
Package p = Package.getPackage( "com.example" ); //(returns non-null)

ただし、これはハックであり、パッケージに属するクラスの名前を事前に知っておく必要があります。

そこで問題は、ClassLoader が何かを実行したかどうかに関係なく、Package のインスタンスを名前で取得する方法はあるのかということです。この状況でクラスローディング/パッケージがどのように機能するかについての私の仮定は正確ですか?

4

3 に答える 3

11

または、クラスのルート ディレクトリを出発点として使用し、すべての *.class ファイルとサブ ディレクトリを確認することもできます。これは、すべての .class ファイルが存在する場所が事前にわかっている場合にのみ機能します。

このすべての原因は、Java には動的なクラスローディングがあるため、コンパイル時や起動時にさえわからない場所から実行時にクラスをロードできるからです。したがって、パッケージの概念は、クラスを検索するために使用できるディレクトリではなく、ロードされたクラスの単なる名前空間です。

于 2009-11-30T09:31:43.453 に答える
6

注釈を調べる必要があるため、これが必要だと思います。それ以外の場合は、操作のみが注釈にアクセスするパッケージ参照を持つことに興味がありません。これは、いくつかの注釈を付けて定義された package-info.java も持っているという仮定につながります。

確認すると、package-info クラスが通常のクラスとしてロードjava.lang.Packageされていることがわかります。getPackageInfo

私は同じ問題を抱えていて、この解決策を思いつきました。

public static Package getPackage(String packageName) throws ClassNotFoundException {
    Class.forName(packageName+".package-info"); // makes sure package info exist and that the class loader already knows about the package
    return Package.getPackage(packageName);
}
于 2015-03-15T13:40:21.653 に答える
5

残念ながら、あなたの仮定は有効ではありません。クラスローダは、クラスをロードするときにパッケージのブックキーピングを行います。

にワイルドカードを渡してClassLoader.getResources、強制的にパッケージ内のクラスを取得することができます。これにより、作業が行われます。

を呼び出す独自の ClassLoader を作成できますがdefinePackage、使用中の通常のバニラ クラスローダーでは役に立ちません。

于 2009-11-29T20:58:57.820 に答える