LoginSignup
8
4

More than 3 years have passed since last update.

enumの比較は==がつよつよ、equalsはよわよわ【Java】

Posted at

理由

==はNullPointerExceptionが発生しない/ equalsは発生する

ぬるぽ確認
public class EnumNullPointerExceptionTest {

    enum Season { SPRING, SUMMER, AUTUMN, WINTER; }

    public static void main(String[] args) {
        Season season = null;
        if (season != Season.SPRING) {
            System.out.println("季節は春ではありません。");
        }

        if (!season.equals(Season.SPRING)) {
            System.out.println("季節は春ではありません。");
        }
    }
}
実行結果
季節は春ではありません。
Exception in thread "main" java.lang.NullPointerException
    at EnumNullPointerExceptionTest.main(EnumNullPointerExceptionTest.java:13)

==は通って、equlasでぬるぽで怒られた(実際に通ったのは、!=だけども)。

NullPointerExceptionが発生しない==つよつよ:blush:
NullPointerExceptionが発生しちゃうequlasよわよわ:sweat:

==は型変換がないため無駄がない(速い)/ equalsはObject型への型変換があるため無駄がある(遅い)

==の処理時間計測
public class EnumSpeedTest1 {

    enum Season { SPRING, SUMMER, AUTUMN, WINTER; }

    public static void main(String[] args) {
        Season season = Season.SPRING;

        long startTimeMs = System.currentTimeMillis();
        for (int i = 0; i < 2000000000; i++) {
            if (season == Season.SPRING) {}
        }
        long executionTimeMs = System.currentTimeMillis() - startTimeMs;
        System.out.println("比較を20億回繰り返すのにかかった時間は" + executionTimeMs + "ミリ秒です");
    }
}
==の実行結果
比較を20億回繰り返すのにかかった時間は2ミリ秒です
equlasの処理時間計測
public class EnumSpeedTest2 {

    enum Season { SPRING, SUMMER, AUTUMN, WINTER; }

    public static void main(String[] args) {
        Season season = Season.SPRING;

        long startTimeMs = System.currentTimeMillis();
        for (int i = 0; i < 2000000000; i++) {
            if (season.equals(Season.SPRING)) {}
        }
        long executionTimeMs = System.currentTimeMillis() - startTimeMs;
        System.out.println("比較を20億回繰り返すのにかかった時間は" + executionTimeMs + "ミリ秒です");
    }
}
equalsの実行結果
比較を20億回繰り返すのにかかった時間は4ミリ秒です

わずかだけど、==の方は型変換しないから速いね。

型変換がなくて無駄がない==つよつよ:relaxed:
型変換が必要で無駄があるequalsよわよわ:sweat:

==はコンパイル時に型チェックがある/ equalsは型チェックない

コンパイル確認
public class EnumCompileTest {

    enum Season { SPRING, SUMMER, AUTUMN, WINTER; }
    enum Color { RED, GREEN, BLUE; }
    enum Animal { DOG, CAT; }

    public static void main(String[] args) {
        if (Season.SPRING.equals(Color.RED)) {}
        if (Season.SPRING == Animal.CAT) {}
    }
}
コンパイル結果
$ javac EnumCompileTest.java
EnumCompileTest.java:10: エラー: 型SeasonとAnimalは比較できません
        if (Season.SPRING == Animal.CAT) {}
                          ^
エラー1個

型が違う==の比較は怒られた。

コンパイル時に型チェックがある==つよつよ:relaxed:
コンパイル時に型チェックないequalsよわよわ:sweat:

番外:なぜenumは==で比較できるのか?

言語仕様には、こう書いてあるよ。
8.9.1. Enum Constants

Because there is only one instance of each enum constant, it is permitted to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.

there is only one instance of each enum constantってことは、
enumのインスタンスはシングルトンなんだね。だから、==で比較できると。

参考

8
4
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
8
4