1

Java プログラムが jar ファイルからクラスをインポートするシナリオを考えてみましょう。同じクラスが 2 つ以上の jar ファイルに存在する場合、問題が発生する可能性があります。

  1. そのようなシナリオでは、プログラムによってインポートされたクラスは何ですか? タイムスタンプが古いクラスですか??

  2. このような合併症を避けるために私たちが従うことができる慣行は何ですか.

編集:これは一例です。my1.jar と my2.jar という 2 つの jar ファイルがあります。両方のファイルに com.mycompany.CrazyWriter が含まれています

4

6 に答える 6

2

デフォルトでは、クラスは順番に検索されるクラスパスを使用してClassLoaderによってロードされます。

同じクラスの実装が2つある場合、クラスローダーが最初に見つけたものがロードされます。

クラスが実際には同じクラスではない場合(同じ名前で異なるメソッド)、それを使用しようとすると例外が発生します。

複数のクラスローダーを使用して、1つのVMに同じ名前の2つのクラスをロードできます。OSGIフレームワークは、多くの複雑さを管理し、正しいバージョンがロードされていることを確認します。

于 2010-01-21T08:54:12.463 に答える
0

まず、同じクラスがさらに2つのjarファイルに存在することを意味していると思います...

今、あなたの質問に答えます:

  1. どのクラスがインポートされるかは、クラスローダーとJVMによって異なります。どのクラスになるかは保証できませんが、通常のクラスローダーでは、クラスパスの最初のjarファイルのクラスになります。
  2. 同じクラスを複数のjarファイルに入れないでください。システムクラスをオーバーライドする場合は、を使用して-bootclasspathください。

編集:この回答に関するコメントの1つに対処します。理論的には、異なるjarファイルから同じパッケージから2つのクラスをロードするべきではないため、jarをシールすることで違いが生じると当初は考えていました。ただし、いくつかの実験の結果、少なくともデフォルトのセキュリティプロバイダーでは、この仮定は当てはまらないことがわかりました。

于 2010-01-21T08:56:13.183 に答える
0

ClassLoaderは、クラスのロードを担当します。ClassPathをスキャンし、最初に見つかったクラスをロードします。ClassPathに同じJarが2回ある場合、または同じクラスの2つの異なるバージョン(つまりcom.packagename.Classname)を含む2つのJarがある場合、最初に見つかったものがロードされます。

クラスパスに同じjarが2回存在しないようにしてください。

于 2010-01-21T08:56:21.593 に答える
0
  1. 「同じクラスがさらに2つのクラスに存在する」という意味 がわかりません

    内部/ネストされたクラスを意味する場合、それらは異なる名前空間にあるため、問題はないはずです。
    すでに回答されているように、さらに2つのJARを意味する場合、クラスパスの順序が使用されます。

  2. 回避する方法は?
    クラスの重複を避けるために、パッケージは 1 つの JAR にのみ含める必要があります。java.util.Date2 つのクラスがとのように同じ単純な名前を持っていてjava.sql.Dateも、異なるパッケージに含まれている場合、それらは実際には異なるクラスです。それらを区別するには、少なくともクラスの 1 つからの完全修飾名を使用する必要があります。

于 2010-01-21T09:22:38.757 に答える
0

使用されているクラスのバージョンを見つけるのに問題がある場合は、jwhich が役立つ可能性があります: http://www.fullspan.com/proj/jwhich/index.html

于 2010-01-21T09:27:46.200 に答える
0

同じクラスがさらに 2 つの jar に存在する場合、問題が発生するはずです。

どういう意味?なぜこれ問題になるのでしょうか?

そのようなシナリオでは、プログラムによってインポートされたクラスは何ですか? (タイムスタンプが古いクラス??)

クラスが 2 つの JAR に存在する場合、クラスはクラス パス上の最初の JAR からロードされます。引用クラスパスの設定(引用部分はアーカイブファイルにも適用されます):

複数のクラスパス エントリを指定する順序は重要です。Java インタープリターは、クラスパス変数に表示される順序でディレクトリ内のクラスを検索します。上記の例では、Java インタープリターは最初に必要なクラスをディレクトリで探しますC:\java\MyClasses。そのディレクトリに適切な名前のクラスが見つからない場合にのみ、インタプリタはC:\java\OtherClassesディレクトリを調べます。

つまり、特定の順序が必要な場合は、JAR ファイルをクラス パスで明示的に列挙するだけです。これは、アプリケーション サーバー ベンダーが一般的に使用するものです。製品の特定のクラスにパッチを適用するには、パッチを適用したクラスを含む JAR (例: CR1234.jar) をクラス パスのメイン JAR (例: ) の前に置きますweblogic.jar

このような合併症を避けるために私たちが従うことができる慣行は何ですか.

まあ、明白な答えは、それをしないことです (または、上記のサンプルのように意図的にのみ)。

于 2010-01-21T10:17:10.323 に答える