2153 Stimmen

Vergleich von Java-Enum-Mitgliedern: == oder equals()?

Ich weiß, dass Java-Enums zu Klassen mit privaten Konstruktoren und einer Reihe von öffentlichen statischen Mitgliedern kompiliert werden. Wenn ich zwei Mitglieder einer gegebenen enum vergleiche, habe ich immer .equals() z.B.

public useEnums(SomeEnum a)
{
    if(a.equals(SomeEnum.SOME_ENUM_VALUE))
    {
        ...
    }
    ...
}

Ich bin jedoch gerade auf einen Code gestoßen, der den Gleichheitsoperator verwendet == anstelle von .equals():

public useEnums2(SomeEnum a)
{
    if(a == SomeEnum.SOME_ENUM_VALUE)
    {
        ...
    }
    ...
}

Welchen Operator sollte ich verwenden?

7 Stimmen

Ich bin gerade über eine sehr ähnliche Frage gestolpert: stackoverflow.com/questions/533922/

73 Stimmen

Ich bin überrascht, dass in all den Antworten (insbesondere in der von polygenelubricants, die detailliert erklärt, warum == funktioniert) ein weiterer großer Vorteil von == nicht erwähnt wurde: dass es explizit macht, wie Enums funktionieren (als eine feste Menge von Singleton-Objekten). Bei equals könnte man meinen, dass es irgendwie mehrere Instanzen der gleichen Enum-'Alternative' geben kann.

3 Stimmen

SomeEnum.SOME_ENUM_VALUE.equals(a) löst niemals eine NullPointerException aus, während a.equals(SomeEnum.SOME_ENUM_VALUE) dies möglicherweise tut.

17voto

Mohsen Zamani Punkte 426

Eine der Sonar-Regeln lautet Enum values should be compared with "==" . Die Gründe dafür sind die folgenden:

Prüfung der Gleichheit eines Aufzählungswertes mit equals() ist absolut gültig, weil ein Enum ein Objekt ist und jeder Java-Entwickler weiß == sollte nicht verwendet werden, um den Inhalt eines Objekts zu vergleichen. Gleichzeitig ist die Verwendung von == über Enums:

  • bietet denselben erwarteten Vergleich (Inhalt) wie equals()

  • ist null-sicherer als equals()

  • bietet eine (statische) Überprüfung zur Kompilierzeit und keine Überprüfung zur Laufzeit

Aus diesen Gründen ist die Verwendung von == sollte vorgezogen werden gegenüber equals() .

Und nicht zuletzt die == auf Enums ist wohl lesbarer (weniger langatmig) als equals() .

16voto

ChrisCantrell Punkte 3663

Hier ist ein grober Zeittest, um die beiden zu vergleichen:

import java.util.Date;

public class EnumCompareSpeedTest {

    static enum TestEnum {ONE, TWO, THREE }

    public static void main(String [] args) {

        Date before = new Date();
        int c = 0;

        for(int y=0;y<5;++y) {
            for(int x=0;x<Integer.MAX_VALUE;++x) {
                if(TestEnum.ONE.equals(TestEnum.TWO)) {++c;}
                if(TestEnum.ONE == TestEnum.TWO){++c;}              
            }
        }

        System.out.println(new Date().getTime() - before.getTime());
    }   

}

Kommentieren Sie die IFs nacheinander aus. Hier sind die beiden Vergleiche von oben in disassembliertem Byte-Code:

 21  getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
 24  getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
 27  invokevirtual EnumCompareSpeedTest$TestEnum.equals(java.lang.Object) : boolean [28]
 30  ifeq 36

 36  getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
 39  getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
 42  if_acmpne 48

Die erste (equals) führt einen virtuellen Aufruf durch und prüft den Rückgabewert auf dem Stack. Die zweite (==) vergleicht die Objektadressen direkt auf dem Stack. Im ersten Fall gibt es mehr Aktivität.

Ich habe diesen Test mehrere Male mit beiden Investmentfonds nacheinander durchgeführt. Die "=="-Variante ist immer etwas schneller.

11voto

Suraj Chandran Punkte 23973

Im Falle von enum ist beides richtig!!

9voto

Tomas Punkte 1274

Die Verwendung von etwas anderem als == um Enum-Konstanten zu vergleichen, ist unsinnig. Es ist wie Vergleichen class Objekte mit equals - Tun Sie es nicht!

Allerdings gab es einen bösen Fehler (BugId 6277781 ) in Sun JDK 6u10 und früher, die aus historischen Gründen interessant sein könnten. Dieser Fehler verhinderte die korrekte Verwendung von == auf deserialisierte Enums, obwohl dies wohl eher ein Eckfall ist.

7voto

Enums sind Klassen, die eine Instanz (wie Singletons) für jede Aufzählungskonstante zurückgeben, die durch public static final field (unveränderlich), so dass == Operator verwendet werden, um ihre Gleichheit zu überprüfen, anstatt mit equals() Methode

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X