2

私はある人に、String.equals メソッドを使用して 2 つの文字列値を比較する必要があることを伝えていました。Java で == 演算子を単純に使用して文字列を比較することはできません。文字列値を比較しますが、String オブジェクト参照値です。

私は彼に見せるためにこの例を書きましたが、驚いたことに、== 演算子の場合は常に true と出力されます。コードは次のとおりです。

public void exampleFunc1(){

    String string1 = "ABC";
    String string2 = "ABC";

    if(string1 == string2)
        System.out.println("true");
    else{
        System.out.println("false");

    }   
    System.out.println(" Are they equal "+(string1 == string2)); // this shouldn't print True but it does
    System.out.println(" Are they equal "+(string1.equals(string2)));

}

出力:-

それらは真に等しいですか

それらは真に等しいですか

ここでの質問は、両方のオブジェクトが同じインスタンスであることを除いて、オブジェクトの == 演算子が true を出力できるのはどのような状況でしょうか?

4

3 に答える 3

2

String数少ない特殊なケースの 1 つです。

クラスStringは、「interned」Stringの特別なプールを保持します。メソッドはこのプールをmyString.intern()検索します。myStringプール内Stringに同じ内容のものが既に存在する場合は、それへのポインターが返されます。そうでない場合は、myStringが追加されます (そしてポインタが返されます)。

あなたが言うときmyString= myString.intern() ;、あなたは事実上myString、共有されたコピーまたはその基礎となるStringものを将来の共有のために利用できるようにしています(そして重複はありません)。s を作成するほとんどのライブラリ メソッドString、特にStringリテラルはこの影響を受けます。

「インターン」の他のケースは、ラッパータイプIntegerLongなどで発生します。それらにはコンストラクターがありませんが、valueOf()可能な場合は事前に構築された共有オブジェクト (通常はゼロに最も近い 256 の値) を返す静的メソッドと、できません。これらの型は s よりも軽量であるため、後者はあまり問題になりませんStringLongたとえば、ペイロードはわずか 8 バイトです。 空でも16バイト程度Stringのaが含まれています。char[]

あなたの質問に答えるために、「インターン」メカニズムを当てにすることはできません。それらは過去に変更されており、将来 (またはある JVM から別の JVM にさえ) 変更される可能性があり、コードが使用できなくなります。常に使用しますequals

于 2013-09-01T04:59:09.673 に答える
1

使用する必要があります

String string1 = new String("ABC");

String string2 = new String("ABC");

そうすれば、あなたが思っているようにすべてが正しくなるでしょう。

この場合、「ABC」は単なる const 文字列への参照です。

于 2013-09-01T04:59:52.270 に答える
0

コンパイラが割り当てを最適化し、1 つの String オブジェクトのみを作成している可能性があります。明示的な String コンストラクターを使用すると、==操作は期待どおりに動作するはずです。

于 2013-09-01T05:01:21.063 に答える