可変長固定長

IT関係の話題が中心

Stringクラスを==演算子で文字列比較しないで! 文字列比較はequalsメソッドで

こんな基本的なことさえ身に付いていないjavaエンジニアが多いので書いておきます。Stringクラスのオブジェクトが参照している文字列を比較する際、==演算子で比較していませんか?

 

それ、NGです。Stringクラスの==演算子は文字列の比較ではなく、オブジェクトの参照情報の比較です。Stringクラスのオブジェクトが管理する文字列比較を行いたい場合はequalsメソッドを使いましょう。

 

 

  

 

==演算子とequalsメソッドの違い

Stringクラスの==演算子で比較する場合とequalsメソッドで比較する場合の違いをみておきましょう。

 

  • ==演算子 …Stringオブジェクトが保持している参照を比較する
  • equalsメソッド …Stringオブジェクトが管理している文字列を比較する

 

Stringクラスではequalsメソッドの取り扱いが異なります。例えばStringBufferクラスでは==演算子でもequalsメソッドでも、オブジェクトが保持している参照を比較することになります。

 

ビギナーの方は==演算子を文字列比較に使いがちですが、予期せぬバグを生むことに繋がりますので注意しましょう。

 

 

文字列比較を==演算子で行う問題点

Stringクラスで==演算子を使って文字列比較をすると問題が生じます。例えば次のコードをみてみましょう。

 

String strA = new String("strA");
String strB = new String("strA");
if (strA == strB) {
System.out.println("True");
}

 

このコードでは"True"は出力されません。

strAとstrBには、たしかにどちらのオブジェクトにも"strA"という文字列を管理されています。しかし、その文字列を比較する際に==演算子を利用すると、strAオブジェクトの参照とstrBオブジェクトの参照を比較することになるためです。

 

ではなぜstrAオブジェクトとstrBオブジェクトの参照は異なるのでしょうか。それはどちらもnewによって新しくオブジェクトを生成しているためです。

 

ちなみに、Stringクラスでは文字リテラルでオブジェクトを作成した場合、同一のオブジェクトを参照することになります。例えば次のコードをみてください。

 

String strA = "strA";
String strB = "strA";
if (strA == strB) {
System.out.println("True");
}

 

このコードでは"True"は出力されます。

==演算子で参照情報の比較を行っていますが、strAもstrBも同一の"strA"という参照情報を保持しているためです。javaでは、文字リテラルでStringクラスのオブジェクトを生成した場合、リソースを効率的に保つため同一のオブジェクトを参照しています。

 

 

文字列比較はequalsメソッドを使おう

Stringクラスの文字列比較に==演算子を利用する問題点について述べてきました。ではどうやって文字列比較をすることが正しいかというと、Stringクラスには文字列比較用のequalsメソッドが用意されています。

 

equalsメソッドによってStringオブジェクトが管理している文字列を正しく比較することができます。次のコードをみてください。

 

String strA = "strA";
String strB = new String("strA");
String strC = strB;
if (strA == strB) {
System.out.println("True1");
}
if (strA.equals(strB)) { 
System.out.println("True2");
}
if (strB == strC) {
System.out.println("True3");
}

 

このコードで出力されるのは"True2"と"True3"になります。

 

一つ目のif文は、前述したとおり同じ文字列を管理していても参照が異なればTrueとはなりません。二つ目のif文では、equalsメソッドによって文字列比較をしているためTrueとなります。

 

三つ目のif文では、==演算子で参照比較を行っています。ただ、strCにはstrBの参照を入れているため、それぞれ同じ参照情報を保持しています。そのため、参照比較でTrueとなります。

 

 

以上、基本的なStringクラスの==演算子とequalsメソッドの違いをメモしておきました。