1

重複の可能性:
Java で文字列を比較するにはどうすればよいですか?
Java との文字列比較のデモンストレーション

ここで非常に基本的なことに混乱しています。Java を使い始めて以来、「文字列比較には == を使用しないでください。常に equals を使用してください」といつも言われていました。今、私は OCJP の学習を開始し、いくつかの紛らわしい点に出くわしました。

1)

String s1 = "Monday"; 
String s2 = "Monday";

s1 == s2 は true を返します。

2)次のように定義されたクラスがあるとしましょう:

class Friend {
    String name;

     Friend(String n){
        this.name = n;
    }

     public boolean equals(Object o){
         return ((Friend) o).name == this.name;
     }
}

2 つのオブジェクトのインスタンスを作成します。

Friend f1 = new Friend("1");
Friend f2 = new Friend("1");

f1.equals(f2)true を返します

3) 最後に、メイン メソッドが定義された MyClass があります。

public static void main(String[] args) {
        System.out.println(args[0] == "x");
    }

呼び出しの後、java MyClass xfalse が出力されます。

1、2、3 の違いは何ですか? 2 つの文字列が明らかに異なるオブジェクトを参照しているのに、ケース 1 と 2 で false が返されないのはなぜですか?

4

4 に答える 4

2

Java言語仕様のセクション3.10.5に従って、文字列リテラルはインスタンスを共有するために「インターン」(格納され、1つの共有可能な値を参照)されます。

各文字列リテラルは、クラスString(§4.3.3)のインスタンス(§4.3.1、§12.5)への参照(§4.3)です。文字列オブジェクトには定数値があります。文字列リテラル(または、より一般的には、定数式(§15.28)の値である文字列)は、メソッドString.internを使用して、一意のインスタンスを共有するように「インターン」されます。

これは、2つの文字列リテラルが同じ内部オブジェクトを参照しているため、例1と2で行われているように、を使用して比較すると等しいことを意味します==。ただし、args[0]例3の文字列はリテラルではありませんが、そのインターン値を比較すると、次のように、式は真になります。

System.out.println(args[0].intern() == "x"); //prints true

同様に、例1または2の文字列のいずれかをインターンしない場合、関連する式はfalseになります。

String s1 = "Monday";
String s2 = new String("Monday");
System.out.println(s1 == s2); //prints false
于 2012-10-27T09:03:18.897 に答える
1

短い答えは次のとおりです。文字列プール。ここで簡単な説明を見つけることができます:

Javaの文字列プールとは?

ここでもっと長く:

http://www.dreamincode.net/forums/topic/187631-the-string-pool/

于 2012-10-27T09:08:49.893 に答える
1

hashCode() メソッドでデバッグしてみる

s1.hashCode() must be equal to s2.hashCode() 

しかし

args[0].hashCode() is not equal to "x".hashCode()
于 2012-10-27T09:12:23.747 に答える
0

#1のアプローチを使用して値を初期化Stringすると、両方の変数がメモリ内で同じように参照されるため、 trueが返されるのStringはこのためです。==

ただし、String他の方法で作成される値は、ほとんどの場合、メモリ内の異なる場所を参照するため、==falseを返します。これが、equalsが同等性をチェックするための最良の方法である理由ですString

于 2012-10-27T09:02:40.013 に答える