🟢 はじめに
今回は、Javaを学び始めた方が必ず一度はハマる「==(等価演算子)の罠」について解説します。
例えば、数字の 5 同士を比べると同じになりますが、文字列の "Java" 同士を比べると「違う!」と判定されてしまうことがあります。
なぜそんなことが起きるのか?
実際のコードと、例え話を使って解説したいと思います。
💻 今回のサンプルコード
まずは、こちらのコードとその実行結果を見てみましょう。
public class Main {
public static void main(String[] args) {
// 1. 数字の比較(基本データ型)
short smallNum = 5;
int bigNum = 5;
float fNum = 5.0F;
double dNum = 5.0;
// 2. 文字の比較
char lower = 'y';
char upper = 'Y';
// 3. 文字列の比較(参照型)
String text1 = "Java";
String text2 = new String("Java");
System.out.println("--- 実行結果 ---");
System.out.println("smallNum == bigNum : " + (smallNum == bigNum));
System.out.println("fNum == dNum : " + (fNum == dNum));
System.out.println("lower != upper : " + (lower != upper));
System.out.println("text1 == text2 : " + (text1 == text2));
}
}
【実行結果】
--- 実行結果 ---
smallNum == bigNum : true
fNum == dNum : true
lower != upper : true
text1 == text2 : false ← !?
一番下の text1 と text2 は、どちらも中身は "Java" なのに、なぜ false(一致しない)になってしまうのでしょうか?
順番に謎解きをしていきます🔍
🥤 1. 数字の比較:コップのサイズが違っても中身の量は同じ!
まずは数字の比較です。
ここでは short型の 5 と int型の 5、そして小数の 5.0 同士を比較しています。
結果はどちらも true(同じ!) です。
💡 例え話:違うサイズのコップに入ったジュース
-
short= 小さいコップ 🥛 -
int= 中くらいのコップ 🍺
データを入れる箱(コップ)のサイズは違っても、中に入っているジュースの量が同じ「5ml」であれば、Javaは「中身の量が同じだね!」と判断してくれます。
🆔 2. 文字の比較:大文字と小文字は「出席番号」が違う!
次は文字の比較です。
小文字の 'y' と大文字の 'Y' は違うものか?
(!=)と聞いており、結果は true(はい、違います!) となります。
💡 例え話:コンピュータの世界の出席番号
人間から見れば同じアルファベットの仲間ですが、コンピュータの世界ではすべての文字に「文字コード」という出席番号のようなものが振られています。
小文字の 'y' と大文字の 'Y' には、全く別の番号が割り当てられています。
そのため、Javaは「番号が違うから別物だ!」と厳密に区別します。
🏠 3. 文字列の比較:シェアハウスと新築の一軒家
ここが今日のメインテーマであり、最大の罠です!
中身は同じ "Java" なのに、結果は false(違う!) になってしまいました。
実は、Javaの == という記号は、文字列(String)を比べる時、「中身の文字」ではなく「住んでいる住所(メモリ上の場所)」を比べているのです。
💡 例え話:シェアハウスと、新築の一軒家
String text1 = "Java";
このように "" だけで文字列を作ると、Javaは「Stringコンスタントプール」というシェアハウスに "Java" という文字を住まわせます。
String text2 = new String("Java");
ここがポイント!わざわざ new というキーワードを使っています。
これは「わざわざ新築の一軒家(ヒープ領域)を建てて、そこに新しい "Java" を住まわせて!」という強い命令になります。
【結論】
text1(シェアハウス住まい)と、text2(新築の一軒家住まい)は、名前は同じ "Java" さんでも、住んでいる住所が全く違います。
== は「2人の住所は同じですか?」とチェックする機能なので、false になってしまうというわけです🙅♂️
📝 まとめ:文字の中身を比べたい時はどうする?
基本データ型(int, doubleなど)の == は「中身の値」を比べる。
参照型(Stringなど)の == は「住所(メモリの参照先)」を比べる。
もし、住所ではなく「中身の文字が同じかどうか」を純粋に調べたい時は、== ではなく equals() メソッドを使います!
// これなら中身の文字を比べるので true になる!
System.out.println(text1.equals(text2));
Java Silverなどの資格試験でよく出る引っかけポイントだと言われています。
同じように「 ==でStringを比較する際にfalseになる理由がいまいち分からない😫」と悩んでいる人の参考になれば幸いです🙌