【Java】==演算子を使ったら動かないことがある!?

こんにちは。体育大卒エンジニアの土屋です。

この記事を読んで、もし、「もっとこうしたほうがいい!」とか、「こういう考えもあるよ!」という意見があればどんどんコメントしていただきたいです。学びとして受け止めて今後に生かしていきます。

今回は「Stringの比較」についてです。javaを始めたてで開発を行い、一番最初に躓いた方もいらっしゃるのでは?と思って、自分の学んだことをアウトプットしつつ記事にしました。

Stringの比較は「==」演算子ではなく「.equals」を使うこと

過去に、rubyやphpで書いたことがあるので、同様に「==」演算子でソースを書いたら、それは、javaでは良くない書き方でした…。

言葉で説明するより、実際にソースで見たほうがわかりやすいと思うので、ソースで説明していきます。

String hogeA = "aaa";
String hogeB = "aaa";

    if (hogeA == hogeB) {
        System.out.println("等しい");
    }else{
        System.out.println("等しくない");
    }

①のパターンだと、結果は「”等しい”」になります。

では次の②のパターンはどうなるでしょう。

Integer hogeA = new Integer(5);
Integer hogeB = new Integer(5);
System.out.println(hogeA == hogeB);

 

結果は、「false」(等しくない)です。

参照型変数の比較は、①の「”aaa”」や②の「5」という値同士を、比較しているのではなく、実際はhogeAの参照先のインスタンスとhogeBの参照先のインスタンス同士を比較しているので、その内部の値まで比較できておりません。

図1のように図で表すと赤枠が比較されているイメージです。

少し図が分かりづらいのですが、メモリ上のhogeAのインスタンスとhogeBのインスタンスは違う位置にnewされているのでそれぞれアドレス(番地)が異なります。

なので、結果は「false」と出てしまうのです。

さらに、その内部の値「”aaa”」は比較対象ではありませんね。

図1

以上より、「==」演算子だと、実際に比較したい値が比較できていません。

なので「.equals」メソッドの出番です。

②のソースで「.equals」メソッドを使います。

Integer hogeA = new Integer(5);
Integer hogeB = new Integer(5); 

System.out.println(hogeA.equals(hogeB));

すると、結果は「true」(等しい)となりました。

equalsメソッドでは、hogeAの参照先のインスタンスの内部で持つ値「5」とhogeBの参照先のインスタンスの内部で持つ値「5」同士を比較しているので、「true」になります。

図で表すと図2の様なイメージです。

今度はインスタンスの内部の値まで比較できています。

図2

ここで「参照型」とたくさん出てきましたが参照型(参照型変数)とは一体なんぞや。。?と思った方に。

基本データ型変数と参照データ型変数について

【基本データ型】boolean,byte,char….など

基本データ型の変数というのは(プリミティブ型ともいう)、型によってその大きさ(bit数)がきっちり過不足無く決まっていることです。変数を宣言した時点でメモリ内のその変数の使用領域を過不足なく確保できるわけです。その決まった領域内に(その型の範囲内の値ならば)どんな値でも保持することができるんです。

【参照型】配列型、クラス型、インタフェース型のもの

値(配列)そのものを保持するのではなく、その値(配列)が置いてある場所を示すコードを保持している変数を、参照型変数と言います。

下記のサイトにわかりやすく載っていたので引用させていただきました。

https://nobuo-create.net/sanshougata/

以上より、javaの実装では「==」演算子より「.equale」を使うことが望ましいのです。

equalsメソッドで文字列を比較するときの注意点

equalsメソッドで文字列を比較する時、

例えば、hogeAの値が”hogehoge”かどうかを比較したい時、どのような書き方をしますか。

まずは、パターン1

パターン1

"hogehoge".equals(hogeA);

続いてパターン2

パターン2

hogeA.equals("hogehoge");

 

パターン1とパターン2では、意味は同じですが、結果に違いが出てくる場合があります。

パターン1の場合、同じ値であれば「true」、異なる場合「false」と結果が出力されます。

しかし、パターン2の場合、hogeAが「null」だった場合、NullPointerException(例外エラー)が発生し、等しいかどうかを比較する前に実行できないため、結果も出力されません。

どちらの書き方が良いのか、というのは状況によって変わってくるかもしれませんが、ちょっとした書き方の違いによって、この様な結果の違いがあることを理解する必要があります。

様々な場面や機能に合ったコードを書けるエンジニアへとなれる様、また、私のような、始めたてのエンジニアの方の役に立つ様、これからもアウトプットしていきたいと思います。

以上、javaの「Stringの比較」についてでした。

 

 

 

 

 

 

 

label, , ,

書いた人

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です