1

2つの単純なJavaアプリケーションを想像してみてください。どちらも、次のような列挙型ファイルを含む同じJARファイルを実装しています。

enum enum1{
   value1;
}

どちらのアプリケーションでも、enum1.value1のハッシュコードを出力します。

System.out.print(enum1.value1.hashCode());

2つのアプリケーションが実装するJARファイルが同じであっても、ハッシュコードが等しくないため、JVMはどのように機能しますか?

両方のアプリケーションが実装する同じJARファイルであるため、ハッシュコードが等しくないのはなぜですか?

編集
データベースにアクセスする2つのアプリケーションがあります。それらは同じJVM内で実行されます。アプリケーション1がデータベースに書き込んでいるとき、アプリケーション2が順番を待たなければならないように(つまり、アプリケーション1によってロックが解放されたとき)、ロックメカニズムを実装したいと思います。私の解決策は、可能であれば、いくつかのReentrantLocksが宣言されているインターフェイス、またはロックとして機能し、2つのアプリケーションで使用される列挙型を作成することです。ただし、同期できるのは同じオブジェクトのみであるため、インターフェイス/列挙型のインスタンスは両方のアプリケーションで同じである必要があります。

編集2
これはアーキテクチャです:

App1.jar              Commons.jar         App2.jar
App1Main.class        Commons.class       App2Main.class 

App1とApp2の両方にCommons.jarが含まれています。commons.classは、単純なシングルトンクラスです。App1とApp2の両方で、コモンズインスタンスのハッシュコードを出力します。

System.out.println(Commons.getInstance().hashCode());

どちらのJavaアプリケーションも「java-jarapp1」と「java-jarapp2」のように実行されるため、実行中のプロセスは2つあります。

しかし、それらは異なるハッシュコードを出力します。つまり、異なるクラスローダーによってロードされているため、私が信じていることです(間違っている場合は修正してください)。しかし、両方のアプリでクラスローダーを印刷すると、神秘的なものが到着します。

System.out.print(ClassLoader.getSystemClassLoader().hashCode());

その場合、ハッシュコードは両方のアプリケーションで等しくなります。

4

4 に答える 4

2

同じプロセス内の2つのアプリケーションについて話しているかどうかは明確ではありません。たとえそうであっても、これら2つのアプリケーションに同じjarファイルをロードする別々のインスタンスがある場合、JVMに関する限りClassLoader、2つの列挙型は異なるタイプです。2つのアプリケーションで使用されるプロセス内で単一のタイプが必要な場合は、単一のクラスローダーでロードする必要があります。

于 2012-06-26T07:46:20.877 に答える
1

Object.hashCode()についてはJavadocを参照してください

hashCodeの一般的なコントラクトは次のとおりです。

  1. Javaアプリケーションの実行中に同じオブジェクトで複数回呼び出される場合は常に、オブジェクトのequals比較で使用される情報が変更されていない限り、hashCodeメソッドは一貫して同じ整数を返す必要があります。この整数は、アプリケーションのある実行から同じアプリケーションの別の実行まで一貫している必要はありません。

  2. equals(Object)メソッドに従って2つのオブジェクトが等しい場合、2つのオブジェクトのそれぞれでhashCodeメソッドを呼び出すと、同じ整数の結果が生成される必要があります。

  3. equals(java.lang.Object)メソッドに従って2つのオブジェクトが等しくない場合、2つのオブジェクトのそれぞれでhashCodeメソッドを呼び出すと、異なる整数の結果が生成される必要はありません。ただし、プログラマーは、等しくないオブジェクトに対して個別の整数結果を生成すると、ハッシュテーブルのパフォーマンスが向上する可能性があることに注意する必要があります。

また

これは通常、オブジェクトの内部アドレスを整数に変換することによって実装されます

したがって、あなたの結果は私には完全に正当なようです。ハッシュコードの一貫性が必要な場合は、APIがこのように使用されることを意図していないため、間違っている可能性があります。多分あなたはあなたの目的を言うことができます。

于 2012-06-26T08:01:56.260 に答える
0

JARは、実行される可能性のあるアプリケーションのレシピを含む静的リソースと考えてください。アプリケーションが実際に実行されると、オペレーティングシステムに固有のルールを使用して、すべてのリソースがコンピューターのメモリに読み込まれます。これらのルールは、クラスが同じ仮想メモリアドレスにロードされることを強制しません。

于 2012-06-26T07:47:29.057 に答える
0

enumは、宣言された型クラスを作成する単なるキーワードです(たとえば、enum Dayは、Day extends Enumのようなクラスを持つことを意味します)。classは、独自のハッシュコードを持つJVMで構築されるオブジェクトへの単純なテンプレートです。したがって、明らかに、新しいオブジェクトを作成すると、新しいハッシュコードが取得されます。これが、新しいハッシュコードを取得する理由です。詳細については、次のリンクを参照してください。

http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

「すべての列挙型は暗黙的にjava.lang.Enumを拡張します。Javaは多重継承をサポートしていないため、列挙型は他のものを拡張できません」この点を明確に観察してください。

于 2012-06-26T09:32:17.943 に答える