4

パッケージのXJava コンパイル ユニットで型を使用し、コンパイル ユニット自体で定義されておらず、直接インポートされていないことを考慮してください。Javaコンパイラはどのように効率的に解決しますか? 存在する可能性がいくつかあります。foo.barXXX

  1. Xスターインポート経由でインポートされる可能性がありますa.b.*
  2. Xコンパイル単位と同じパッケージに存在する可能性があります
  3. X言語タイプである可能性があります。つまり、次の場所に存在しますjava.lang

私が見る問題は特に(2.)です。はパッケージ プライベート タイプである可能性があるため、という名前のコンパイル ユニットに存在するX必要さえありません。したがって、コンパイラはクラスパスのすべてのエントリを調べて、パッケージ内のクラスを検索する必要があります。次に、パッケージ内のすべてのクラスを読み取って、が含まれているかどうかを確認する必要があります。XX.javafoo.barfoo.barX

それは非常に高価に聞こえます。特に、単一のファイルのみをコンパイルする場合、コンパイラは type を見つけるためだけに数十のクラス ファイルを読み取る必要がありますX。多くのスター インポートを使用する場合、この手順を多くの型に対して繰り返す必要があります (もちろん、クラス ファイルを 2 回読み取ることはありません)。

では、コンパイル プロセスを高速化するために、同じパッケージから型もインポートすることをお勧めしますか? または、見つけられなかったインポートされていない型を解決するためのより高速な方法はありXますか?

4

2 に答える 2

1

それは非常に高価に聞こえます。

コンパイラがそのようにした場合、コストが高くなります。

しかし実際には、クラスパス、ブートクラスパス、およびソースパス上のすべてのクラス名を含むメモリ内データ構造を構築し、javac実行時にコンパイルされるすべてのクラスのすべてのクラス名解決にそれを使用します。

では、コンパイル プロセスを高速化するために、同じパッケージから型もインポートすることをお勧めしますか? または、私が見つけることができなかったインポートされていない型 X を解決するためのより高速な方法はありますか?

いいえ、いいえ。ほとんど変わらないでしょう。さらに、コンパイラを設計どおりに使用する場合、これが重大なボトルネックになることはほとんどありません。

最も読みやすく信頼性の高いコードを提供する方法でインポートを行うことをお勧めします。

于 2014-06-07T02:47:38.600 に答える
0

したがって、コンパイラはクラスパスのすべてのエントリを調べて、パッケージ foo.bar 内のクラスを検索する必要があります。

それだけClass.forName()です。

次に、パッケージ foo.bar にあるすべてのクラスを読み取って、X が含まれているかどうかを確認する必要があります。

これが何を意味するのかわかりません。

それを介して .class ファイルを探した後、現在のパッケージのソースパスを調べて、適切な名前のファイルClass.forName(),を探す必要がありますnew File(...).exists()

その名前で非公開クラスの各ファイル内を検索するとは確信していません。試してみる必要があります。もしそうなら、それは確かに費用のかかるステップですが、私はそれが行われたとは確信していません.

于 2014-06-06T22:29:16.000 に答える