2013-05-24 9 views
8


複数のスレッドにわたって同じインスタンスのSimpleDateFormatを使用してバグを複製しようとしていました。しかし、私は別の問題を抱えていて、何の答えも見つけられませんでした。新しいSimpleDateFormatは、指定されたdateFormatの同じ参照を常に返します

この単純なコードブロックは、私が見ている問題を再現します。

d1 = [email protected] 
d2 = [email protected] 
d3 = [email protected] 

を次のようにあなたは私がD1およびD2のための新しいオブジェクトを作成しておりますが、彼らは同じになってしまうことを見ることができるように

DateFormat d1 = new SimpleDateFormat("ddMMyyyy"); 
DateFormat d2 = new SimpleDateFormat("ddMMyyyy"); 
DateFormat d3 = new SimpleDateFormat("ddMMyy"); 
System.out.println("d1 = " + d1); 
System.out.println("d2 = " + d2); 
System.out.println("d3 = " + d3); 

のJava 7(1.7_0_21)の下で、この操作の結果は、参照。パターンが異なるので、d3は新しいインスタンスになります。

Javaコンパイル/ランタイムはこの最適化を行いますか?任意のポインタは

+2

実際には( '=='を使って)同じインスタンスですか? – assylias

+2

そして、最後の質問に答える:いいえ、Javaの 'new' **は常に**例外を発生させない限り、新しいオブジェクトを生成します**。 JVMは、それを最適化することはできません。 –

答えて

14

SimpleDateFormatDateFormatSimpleDateFormatスーパー)もFormatDateFormatスーパークラス)toString()が実装されている参考になるので、ObjectクラスからtoString()は、実際にそのコードで、実行されます。今すぐ

public String toString() { 
    return getClass().getName() + "@" + Integer.toHexString(hashCode()); 
} 

SimpleDateFormatのhashCodeが生成されます。どの私

public int hashCode() 
{ 
    return pattern.hashCode(); 
    // just enough fields for a reasonable distribution 
} 

同じpatternの数多くのSimpleDateFormatインスタンスを作成すると、が同じhashCodeとなるため、toString()はこれらのインスタンスに対して同じ結果を返します。

さらに、rixmathによって発見されたように、同じpatternSimpleDateFormatのインスタンスも同等になります。

+0

私はあなたが彼の質問をしなかったと思います。彼は両方の参照(d1、d2)が同じSimpleDateFormatオブジェクトを指している理由を尋ねています。そのハッシュコードを見てください。それは同じです。 –

+0

@Ankur同じハッシュコードは同じインスタンスを意味しません。 – assylias

+0

そうですが、それは問題ではありません。彼は、なぜ2つの変数が異なるものを期待するときに同じオブジェクトを指すのか、困惑しています。 http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#toString() –

5

彼らは異なるインスタンスである、これは

DateFormat d1 = new SimpleDateFormat("ddMMyyyy"); 
    DateFormat d2 = new SimpleDateFormat("ddMMyyyy"); 
    System.out.println(d1 == d2); 

それは同じ[email protected]用として

false 

を印刷してみてください、彼らはクラス名とhashCodeに基づいています。 Object.hashCode APIによると、必ずしも別個のオブジェクトの別個の値を返すわけではありません。

6

SimpleDateFormat実際にはパターンのハッシュコードを返してhashCodeを実装します。

System.out.println("d1 = " + d1 + "/" + System.identityHashCode(d1)); 
System.out.println("d2 = " + d2 + "/" + System.identityHashCode(d2)); 
System.out.println("d3 = " + d3 + "/" + System.identityHashCode(d3)); 

これは、3つの異なる値を出力します:

あなたはSystem.identityHashCode()を使用して、個別のオブジェクトが実際に存在していることを確認することができます。

+1

2つの異なるオブジェクトのアイデンティティハッシュコードも同じである可能性があります。代わりに '=='演算子を使用して、2つのオブジェクトが異なるオブジェクトであることを検証する必要があります。 – SpaceTrucker

+0

@SpaceTrucker:そうです、それは同じかもしれませんが、それは起こりそうもありません。 –

関連する問題