LoginSignup
1
2

More than 3 years have passed since last update.

Javaのequalsは結構気持ち悪い

Posted at

導入

こんにちは、けちょんです。
Java書いてますか?
そんな私はここ数か月コーディングしてません。
焦ってJava goldの勉強を始めました(今日から)
その際気持ち悪かったことがあったので紹介します。

なにが気持ち悪かったか

皆さん、文字列を比較する際、どう比較しますか?

素人プログラマの場合

String str1 = "test";
String str2 = "test";
if (str1 == str2) {
    System.out.print("same");
} else {
    System.out.print("diff");
}

はい、だめですね。
こんなコード書いたら怒られます。はい、私です。
演算子である"=="はオブジェクトのメモリアドレスを比較します。

異なるオブジェクトは基本的に異なるメモリアドレスを保持します。
今回比較したいのはオブジェクトの持つ文字列であるため、意図に反しています。

が、この場合は"same"が出力されます。
String自体が気持ち悪いため、注意が必要です。
本題ではないし、詳しく知らないため省略します。

一般プログラマの場合

String str1 = "1";
String str2 = "1";
if (str1.equals(str2)) {
    System.out.print("same");
} else {
    System.out.print("diff");
}

普通ですね。よく見ます。
でも、皆さんObject.equalsの中身みたことありますか?

中身は、、、

public boolean equals(Object obj) {
    return (this == obj);
}

"=="を使っとるやーーーん

"=="を使っていて怒られた私は大激怒です。

まとめ

文字列の比較はeqaulsも"=="も一緒????

いやいや

もちろんそんなことはありません。

equalsメソッドは、Stringクラスがオーバーライドしています。
以下がString.equalsの中身です。

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String aString = (String)anObject;
        if (coder() == aString.coder()) {
            return isLatin1() ? StringLatin1.equals(value, aString.value)
                              : StringUTF16.equals(value, aString.value);
        }
    }
    return false;
}

これも"=="は使っているものの、メモリアドレスが異なる場合は別の比較を行っていますね。

まとめ

Object.equalsはただの"=="での比較
String.equalsは"=="で比較するものの、比較対象が文字列だった場合は特殊な動きをする(こちらの期待する動き)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2