JAvaトラップ2動物状元

1607 ワード

Javaコード
次のjavaプログラムの印刷結果は何ですか?Javaコード

public class AnimalFarm{   
   public static void main(String[] args){   
        final String pig = "length: 10";   
        final String dog = "length: "+pig.length();   
        System.out.println("Animal are equal:" +pig == dog);     
    }   
}  

このプログラムを表面解析すると,Animal are equal:trueを印刷すべきであると考えられるかもしれない.結局、pigとdogはfinalのStringタイプ変数であり、文字列シーケンス「length:10」に初期化されています.すなわち、pigおよびdogによって参照される文字列は、常に互いに等しい.ただし、==オペレータは、2つのオブジェクトが等しいかどうかをテストしません.2つのオブジェクトの参照が同じかどうかをテストします.この例では、同じオブジェクトを参照するわけではありません.
   Stringタイプのコンパイル期間定数はメモリで定義され、2つのStringタイプの定数式のいずれかで、同じ文字シーケンスを指定すると、同じオブジェクト参照で表されます.定数式がpigとdogを初期化する場合、彼らは確かに同じオブジェクトを指しますが、dogは定数表現で初期化されていません.言語が定数式で許可されている操作に制限されており、メソッド呼び出しが含まれていない以上、このプログラムはAnimal are equal:falseを印刷する必要があります.
  実際にはまだ間違っていて、このプログラムを実行すると、falseだけが印刷されていて、他のものはありません.Aniaml are equalは印刷されていません.なぜこの文字列定数を印刷しないのですか.印刷するのが正しいから、+オペレータはここで問題が発生しました.式が加算するか文字列をリンクするかにかかわらず、==オペレータよりも優先度が高くなります.これに応じて、println方式のパラメータは実際に式が次のように計算されます.
Javaコード
System.out.println(("Animal are equal:"+pig)==dog);  

   このブール式の値はもちろんfalseには、文字列接続オペレータを使用するときに、常に平凡ではない操作を括弧で囲むようなエラーを回避する方法があります.
   できれば、文字列定数のメモリ制限メカニズムに依存するコードは少ないはずです.
   オブジェクト参照を比較する場合は、=オペレータではなくequalsメソッドを優先的に使用する必要があります.オブジェクトの値ではなくオブジェクトの識別子を比較する必要がない限り.上記の原則に従って変更すると、trueが印刷されるのは明らかです.
   
Javaコード
System.out.println("Animal are equal:" +pig.equals(dog));