2016-08-24 17 views
0

なぜこのプログラムが最初のprint文でfalseを出力し、print文でtrueを返しますか? iとi1は2つの異なるオブジェクトなので、最初の文は "true"を出力する必要がありますが、2番目のprint文は "false"を出力して混乱を招きます。常にをnewキーワードを使用してInteger Wrapperクラスを2つ比較する

public static void main(String[] args) { 
     Integer i = new Integer(10); 
     Integer i1 = new Integer(10); 
     System.out.println(i == i1); //printing false 
     i++; 
     i1++; 
     System.out.println(i == i1);//printing true 
    } 
+0

可能性のある重複した[どのように適切にJavaで2つの整数を比較しますか? ](http://stackoverflow.com/questions/1514910/how-to-properly-compare-two-integers-in-java) – ArcticLord

+0

@ Ishan質問の文言をチェックできますか? "最初のステートメントは、"期待どおりの "true"を印刷する必要がありますが、リストには2番目のprintステートメントの場合と同様にfalseを出力する最初のステートメントが表示されます。 –

答えて

5

は、2つの異なるインスタンスを作成します。したがって、以下は常に真です:

new Integer(10) != new Integer(10) 

したがって、最初の行は "false"と表示されます。その後

i++; 

はアンボクシングとボクシングを隠します。これは、と等価である:

i = Integer.valueOf(i.intValue() + 1); 

the Javadoc of Integer.valueOfに記載されているように、(少なくとも)-128から127までの値がキャッシュされている:あなたがi++i1++両方にInteger.valueOf(11)のキャッシュされたインスタンスを取り戻すされ、従って第二ライン印刷"真"。ここで

+0

興味深い。 +500で同じことをすると、実際には2回目のfalseを実際にプリントします。https://ideone.com/yvSSFS – baao

+0

@baaoそれは必ずしも現時点では理想ではありません。 ["このメソッドは常に値を-128〜127の範囲でキャッシュし、この範囲外の他の値をキャッシュすることがあります。]]]](https://docs.oracle.com/javase/7/docs/api/java /lang/Integer.html#valueOf(int))明らかに501はideoneによって現在実行されているJVMによってキャッシュされません。 –

+0

これは意味があります。説明ありがとう! – baao

1

Integer i = new Integer(10); 
Integer i1 = new Integer(10); 

あなたは、これはあなたに二つの異なる参照を与える、Integerクラス型の動的に割り当てられた2つのインスタンスを求めます。

Integer i = 10; 
Integer i1 = 10; 

小さい値のラッパークラスでは、キャッシュされたオブジェクトを使用するため、iとi1の参照は等しくなります。 JLS(強調鉱山)に15.14.2. Postfix Increment Operator ++

i++; 
    i1++; 

がで説明されている:この

添加前

バイナリ数値昇格(5.6.2)はを行います値1と変数の値について必要に応じて、合計は、縮小プリミティブ変換(§5.1.3)*で絞り込まれ、ボクシング変換(§5.1.7)を格納する前に変数の型に変換されます。

注上記バイナリ数値昇格は、(5.1.8)とアンボクシング変換を含むことができること:オペレータが適用される前にアンボクシング変換が起こることを言う

また、以下のノートが重要です値セット変換(5.1.13)。必要に応じて、変数に格納される前に合計に値セット変換が適用されます。 その場合それは、それが割り当てられた整数インスタンスの参照型または箱入りIntegerクラスのいずれかに++演算子を適用した後、最後にそうバックラッパー型

に箱詰めされた手段、あなたが箱入り整数で終わります値はボックス型の正しい範囲にあります。

0

最初は参照比較ですので、値が比較されます(インクリメントしている間はプリミティブintのボックス化されていないため、11にインクリメントされ、再度自動ボックス化されます; i1と同じです)。 2番目の呼び出しは(11 == 11)したがってtrueです。

-1

Integerクラスには他の多くのクラスがあり、equalsメソッドが実装されています。あなたは簡単にこのように整数の2つのインスタンスを比較することができます。

Integer int1 = new Integer(2); 
Integer int2 = new Integer(2); 
if(int2.equals(int1)) { 
    // true 
} 

は、すべてあなた自身のエンティティ/ DTOSにequalsメソッドの実装を検討してください。の

class Car { 
    private String color; 
    private Integer model; 

    public Car(String color, Integer model) { 
    this.color = color; 
    this.model = model; 
    } 

    public String getColor() { return color; } 
    public Integer getModel() { return model; } 

    @Override 
    public boolean equals(final Object obj) { 
    if(this == obj) { 
     return true; // You are actually comparing the same instances 
    } 
    if(obj instanceof Car) { // Now you know both obj are instances of class Car 
     final Car other = (Car) obj; // Safe to cast 
     return Objects.equal(color, other.getColor()) 
     && Objects.equal(model, other.getModel() 
     ; 
    } 
    return false; 
    } 
} 
関連する問題