━目次━
連載3日目です。1日目2日目がまだの人は1日目から読むことをオススメします。
全体はこんな感じ。
【1日目】値(プリミティブ)型と参照(オブジェクト)型の違いをコードと図で解説
【2日目】参照渡しとは?参照型の変数を代入した時の挙動を押さえよう!
【3日目】==とequalsの違いは図で理解すれば絶対間違えない
【4日目】イミュータブルな変数ってなんだ?String型変数の特殊性を知る
参照周りで押さえておきたい内容について4回に渡って解説していきます。
今回はJavaで最初に必ずと言っても良い程直面する
==とequalsの違い
について解説していきます。
「よく分からんけどとりあえず文字列はequalsで比較」程度の理解の人は、
これまでの講義と、図を使えばバッチリ理解できると思います。
それでは3日目いきましょう~(/・ω・)/
==とequalsの違いを図で理解する
ネットで見ると、やれ同値だの等価だの同一性だの小難しいことが文章で書いてあります。
が!
これまでの図を理解していれば2つの比較の違いは一目瞭然です。
たったこれだけです!
値型の変数は左側のスタック領域に格納されるので、==で値の比較ができ、
参照型は実際の値は右側のヒープ領域に格納されるので、equalsで比較します。
おーそういうことか!覚えやすいの!
なので参照型の変数を==で比較する場合は、スタック領域の比較なので「7e41c839」のような参照値を比較することになり、意図した結果が取得できない可能性がでてくるわけです。
実際にコードで確認していきましょう。
==とequalsの違いをコードで確認する
では実際にコードを書いて、意図した結果を得られるか確認してみましょう。
値型の変数を==で比較
まずは簡単な例から。
1 2 3 4 5 6 7 8 9 10 11 |
String msg = ""; int num1 = 1; int num2 = 1; if (num1 == num2) { msg = "==で一緒です"; } else { msg = "==で違います"; } System.out.println(msg); // ==で一緒です |
==での比較なので左側のスタック領域ですね。
値型はスタック領域に実際の値が格納されているので勿論結果は一緒です。
値型の変数をequalsで比較
はい、できません。
↑で貼った図を見れば分かる通りequalsは右側のヒープ領域を比較するけれど、値型は左側のスタック領域にしか値を持っていないためです。
実際に以下のように怒られます。
参照型の変数を==で比較
これまでの図で見たように、参照型の変数は
・左側のスタック領域に参照値
・右側のヒープ領域に実際の値
をもっています。
==は左側のスタック領域の比較なので、
参照型の変数を==で比較すると参照値の比較になることが分かると思います。
コードで見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
String msg = ""; int[] arr1 = {1,2,3}; int[] arr2 = {1,2,3}; if (arr1 == arr2) { msg = "==で一緒です"; } else { msg = "==で違います"; } System.out.println(msg); // ==で違います // 変数の中を確認してみる System.out.println(arr1); // [I@193c4163 System.out.println(arr2); // [I@d1cc4e9 |
格納されている配列の中身は一緒でも「違います」とでましたね。
そこで変数の値(参照値)を出力するとやはり異なることが確認できました。
これは図で表すとこういうことが起きています。
新しく変数を定義すると新しくメモリが確保されるので、参照値が異なるのは当然ですよね。
(4日目の講義でStringはそうならないことには触れますが…)
参照型の変数をequalsで比較
では最後に参照型変数のequalsでの比較を見てみましょう。
ちなみに配列の比較は特別にArrays.equalsというものが用意されているのでそれを使います。
1 2 3 4 5 6 7 8 9 10 11 |
String msg = ""; int[] arr1 = {1,2,3}; int[] arr2 = {1,2,3}; if (Arrays.equals(arr1, arr2)) { msg = "equalsで一緒です"; } else { msg = "equalsで違います"; } System.out.println(msg); // equalsで一緒です |
equalsの比較では右側のヒープ領域の値を比較してくれるので、今度は「一緒です」となりましたね。
↑の図で考えればそんなに難しくないよね^^
3日目はここまで
==とequalsの違い、値型と参照型での比較に使われる値など分かってもらえたかと思います。
Javaで変数を扱う時は常に、左側にスタック領域、右側にヒープ領域の図を頭でイメージしておくと綺麗なコードが書き易い(無駄なメモリを使わない)と思うので、覚えておいてください。
ただ、このあたりの話をややこしくするのがString型の特殊性です。
次回は最終回ということで、このラスボスを倒して集中講義を終えることとしましょう。
それでは!また明日!!
人気の記事だけ集めたので是非覗いていってください^^
厳選!目的別にオススメ記事を紹介-あなたの欲しい情報がここに-