63099


String型について質問です。

**_ソースコード_**

[code]

    String name1 ="ネコ";
    
    String name2 ="ネコ";
    
    boolean q1=name1==name2;   
    System.out.println("name1==name2:"+name1==name2);  //※1
    System.out.println("q1:"+q1); 
    
[/code]

上記のコードを実行すると、下記のように結果が表示されました。

**_メッセージ_**

[code]

    false
    q1:true
    
[/code]

疑似プリミティブ型同士を `==`
でつなぐとtrueになるらしいのですが、※1ではfalseになってしまいました。あとよく分からないですが"name1==name2:"の部分も消えてしまったのもどうしてでしょうか？


CC BY-SA 4.0
2020-02-16T09:16:44.987
63088
2020-02-17T22:23:07.880
2020-02-17T22:23:07.880
19110
37786
question
java
String型を==で比較したときの挙動が予想と違う


Javaでは`==`より`+`のほうが優先順位が高いため

[code]

    System.out.println(("name1==name2:" + name1) == name2);
    
[/code]

と解釈されてしまうことが原因です。`"name1==name2:" +
name1`は`name2`とは異なるインスタンスになるため、`false`が出力されます。

このことは

[code]

    System.out.println("name1==name2:" + (name1 == name2));
    
[/code]

とカッコを明示的に書くことで所望の結果が得られることからも確認できます。

参考:[演算子の優先順位と結合規則 - 演算子 -
Java入門](https://www.javadrive.jp/start/ope/index4.html)

**2月17日追記**  
前の版だと、文字列結合の結果が`"ネコ"`なら必ず`true`になるとも読める表現になっていて、不正確でした。

[code]

    String empty = "";
    String name3 = empty + name1;
    
    System.out.println(System.identityHashCode(name1));
    System.out.println(System.identityHashCode(name2));
    System.out.println(System.identityHashCode(name3));
    
    // 手元では
    // 424058530
    // 424058530
    // 321001045
    
[/code]


CC BY-SA 4.0
2020-02-16T09:31:15.707
63089
2020-02-17T13:06:26.873
2020-02-17T13:06:26.873
13199
13199
63088
answer


> 疑似プリミティブ型同士を == でつなぐとtrueになるらしい

[OOPerさんコメント](https://ja.stackoverflow.com/questions/63088/string%e5%9e%8b%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6#comment69087_63088)
でも触れられていますが、Java言語に「疑似プリミティブ型」という概念は存在しませんし、そのような用語を使った解説記事は少々信頼性が疑わしいです。

大原則として、Java言語における文字列(`String`)比較では`==`演算子ではなく **`equals`メソッドを使うべき** です。

`==`演算子による文字列比較は、プログラマの意図しない結果をもたらします。<https://wandbox.org/permlink/EGc2NefxKjmkXA5R>

[code]

    String name1 ="ネコ";
    
    String name3_ne = "ネ";
    String name3_ko = "コ";
    String name3 = name3_ne + name3_ko;  // "ネコ"
    
    System.out.println("name1 == name3: " + (name1 == name3));    // false
    System.out.println("name1 eq name3: " + name1.equals(name3)); // true
    
[/code]

マニアックな例外事項：`intern`メソッドと組合わせるケースに限って、文字型に対する`==`演算子比較は意味をもちます。通常の利用シーンでは`equals`メソッドを使うべきです。


CC BY-SA 4.0
2020-02-17T01:33:14.727
63099
2020-02-17T01:33:14.727
49
63088
answer