3

インポートせずにコンパイル単位で参照できる JRE クラスをプログラムで見つける必要があります (静的コード分析のため)。パッケージローカル クラスは無視できます。JLS によると、パッケージのクラスjava.langは暗黙的にインポートされます。出力は、バイナリ クラス名のリストである必要があります。このソリューションは、プレーンな Java 5 以降 (Guava、Reflectionなどなし) で動作し、ベンダーに依存しない必要があります。

信頼できる Java ベースのソリューションであれば、大歓迎です。


これまでに試したことに関するメモを次に示します。

一見すると、問題は「パッケージからすべてのクラスをロードする方法は?」に要約されるように見えますが、これはもちろん事実上不可能ですが、いくつかの回避策があります (たとえば、これこれ、およびそこにリンクされているブログ投稿)。しかし、複数のクラスローダーの問題が存在しないため、私の場合ははるかに単純です。java.langシステム/ブートストラップ クラスローダによって常に何かをロードでき、そのパッケージに独自のクラスを作成することはできません。問題は、システムのクラスローダーが、リンクされたアプローチが依存するクラスパスを公開しないことです。

これまでのところ、システム クラスローダーのクラス パスにアクセスできませんでした。これは、使用している HotSpot VM で をObject.class.getClassLoader()返しnull、委譲によってThread.currentThread().getContextClassLoader()ロードできますjava.lang.Objectが、それ自体にはクラスパスが含まれていないためです。したがって、このような解決策は私にはうまくいきません。また、保証されたシステム プロパティのリストには、この種のクラスパス情報 ( などsun.boot.class.path) を持つプロパティは含まれません。

rt.jarが存在すると想定する必要がまったくなく、システム クラスローダーが使用するリソースのリストをスキャンする必要がなかったとしたら、それは素晴らしいことです。このようなアプローチは、ベンダー固有の JRE 実装に関してより安全です。

4

2 に答える 2

0

OK、私は質問を読み違えました。JLSを確認すると、次のようになります。

「すべてのコンパイル単位は、事前定義されたパッケージ java.lang で宣言されたすべてのパブリック型名を暗黙のうちにインポートします。まるで、宣言 import java.lang.*; が各コンパイル単位の先頭でパッケージ ステートメントの直後に現れたかのようです。その結果、名前はこれらすべてのタイプは、すべてのコンパイル ユニットで単純な名前として使用できます。」

( http://docs.oracle.com/javase/specs/jls/se7/html/jls-7.html )

含まれるタイプを知りたい場合は、Javaのバージョンごとに異なります...

于 2014-01-13T22:40:26.793 に答える