Effizientes Verwalten von Konstanten mit Java Enums

Enum wurde in Java 1.5 als neuer Typ eingeführt, dessen Felder aus einer festen Menge von Konstanten bestehen. Zum Beispiel können wir Richtungen als Java Enum mit den festen Feldern EAST, WEST, NORTH und SOUTH erstellen.

Java Enum

In diesem Tutorial lernen wir, wie man ein Enum erstellt. Wir werden uns auch die Vorteile von Enums in Java und die Eigenschaften von Enum-Typen ansehen. Außerdem lernen wir die Verwendung von Java Enum valueOf, enum values, EnumSet und EnumMap anhand von Beispielen.

Java Enum Beispiel

Das Java-Schlüsselwort enum wird verwendet, um einen Enum-Typ zu erstellen. Schauen wir uns das folgende Java Enum-Beispielprogramm an.

package com.journaldev.enums;

public enum ThreadStates {
    START,
    RUNNING,
    WAITING,
    DEAD;
}

Im obigen Beispiel ist ThreadStates das Enum mit den festen Konstantenfeldern START, RUNNING, WAITING und DEAD.

Java Enum vs Konstanten

Nun sehen wir uns an, warum Java Enums besser als normale Konstantenfelder in Java-Klassen sind. Erstellen wir eine ähnliche Konstantenklasse in Java.

package com.journaldev.enums;

public class ThreadStatesConstant {
    public static final int START = 1;
    public static final int WAITING = 2;
    public static final int RUNNING = 3;
    public static final int DEAD = 4;
}

Nun sehen wir, wie sowohl Enum als auch Konstanten in einem Java-Programm verwendet werden:

/**
 * Diese Methode zeigt den Vorteil der Verwendung von Enum gegenüber Konstanten
 */
private static void benefitsOfEnumOverConstants() {
    //Enum-Werte sind festgelegt
    simpleEnumExample(ThreadStates.START);
    simpleEnumExample(ThreadStates.WAITING);
    simpleEnumExample(ThreadStates.RUNNING);
    simpleEnumExample(ThreadStates.DEAD);
    simpleEnumExample(null);

    simpleConstantsExample(1);
    simpleConstantsExample(2);
    simpleConstantsExample(3);
    simpleConstantsExample(4);
    //wir können jede int-Konstante übergeben
    simpleConstantsExample(5);
}

private static void simpleEnumExample(ThreadStates th) {
    if(th == ThreadStates.START) System.out.println("Thread gestartet");
    else if (th == ThreadStates.WAITING) System.out.println("Thread wartet");
    else if (th == ThreadStates.RUNNING) System.out.println("Thread läuft");
    else System.out.println("Thread ist tot");
}

private static void simpleConstantsExample(int i) {
    if(i == ThreadStatesConstant.START) System.out.println("Thread gestartet");
    else if (i == ThreadStatesConstant.WAITING) System.out.println("Thread wartet");
    else if (i == ThreadStatesConstant.RUNNING) System.out.println("Thread läuft");
    else System.out.println("Thread ist tot");
}

Wenn wir uns das obige Beispiel ansehen, haben wir zwei Risiken bei der Verwendung von Konstanten, die durch das Enum gelöst werden.

  1. Wir können jede int-Konstante an die Methode simpleConstantsExample übergeben, aber wir können nur feste Werte an simpleEnumExample übergeben, was Typensicherheit bietet.
  2. Wir können den int-Konstantenwert in der Klasse ThreadStatesConstant ändern, aber das obige Programm wird keine Ausnahme auslösen. Unser Programm funktioniert möglicherweise nicht wie erwartet, aber wenn wir die Enum-Konstanten ändern, erhalten wir einen Compiler-Fehler, der jegliche Möglichkeit von Laufzeitproblemen ausschließt.

Java Enum Methoden

Nun sehen wir uns weitere Funktionen von Java Enum anhand eines Beispiels an.

package com.journaldev.enums;

import java.io.Closeable;
import java.io.IOException;

/**
 * Dieses Enum-Beispiel zeigt alle Dinge, die wir mit Enum-Typen machen können
 *
 */
public enum ThreadStatesEnum implements Closeable {
    START(1) {
        @Override
        public String toString() {
            return "START-Implementierung. Priorität=" + getPriority();
        }

        @Override
        public String getDetail() {
            return "START";
        }
    },
    RUNNING(2) {
        @Override
        public String getDetail() {
            return "RUNNING";
        }
    },
    WAITING(3) {
        @Override
        public String getDetail() {
            return "WAITING";
        }
    },
    DEAD(4) {
        @Override
        public String getDetail() {
            return "DEAD";
        }
    };

    private int priority;

    public abstract String getDetail();

    // Enum-Konstruktoren sollten immer privat sein.
    private ThreadStatesEnum(int i) {
        priority = i;
    }

    // Enum kann Methoden haben
    public int getPriority() {
        return this.priority;
    }

    public void setPriority(int p) {
        this.priority = p;
    }

    // Enum kann Funktionen überschreiben
    @Override
    public String toString() {
        return "Standard-Implementierung von ThreadStatesConstructors. Priorität=" + getPriority();
    }

    @Override
    public void close() throws IOException {
        System.out.println("Schließen von Enum");
    }
}

Java Enum Wichtige Punkte

Hier sind einige wichtige Punkte für Enums in Java.

  1. Alle Java-Enums erweitern implizit die Klasse java.lang.Enum, die die Klasse Object erweitert und die Schnittstellen Serializable und Comparable implementiert. Daher können wir keine Klasse in einem Enum erweitern.
  2. Da enum ein Schlüsselwort ist, können wir den Paketnamen nicht mit ihm beenden, z.B. ist com.journaldev.enum kein gültiger Paketname.
  3. Enum kann Schnittstellen implementieren. Wie im obigen Enum-Beispiel implementiert es die Schnittstelle Closeable.
  4. Enum-Konstruktoren sind immer privat.
  5. Wir können keine Instanz von Enum mit dem Operator new erstellen.
  6. Wir können abstrakte Methoden in Java Enum deklarieren, dann müssen alle Enum-Felder die abstrakte Methode implementieren. Im obigen Beispiel ist getDetail() die abstrakte Methode und alle Enum-Felder haben sie implementiert.
  7. Wir können eine Methode in Enum definieren, und Enum-Felder können sie ebenfalls überschreiben. Zum Beispiel ist die Methode toString() in Enum definiert und das Enum-Feld START hat sie überschrieben.
  8. Java Enum-Felder haben einen Namensraum, wir können Enum-Felder nur mit dem Klassennamen verwenden, wie ThreadStates.START.
  9. Enums können in switch-Anweisungen verwendet werden, wir werden dies im späteren Teil dieses Tutorials sehen.
  10. Wir können ein vorhandenes Enum erweitern, ohne eine vorhandene Funktionalität zu beeinträchtigen. Zum Beispiel können wir ein neues Feld NEW in ThreadStates hinzufügen, ohne eine vorhandene Funktionalität zu beeinflussen.
  11. Da Enum-Felder Konstanten sind, ist es in Java am besten, sie in Großbuchstaben und mit Unterstrichen für Leerzeichen zu schreiben. Zum Beispiel EAST, WEST, EAST_DIRECTION usw.
  12. Enum-Konstanten sind implizit static und final.
  13. Enum-Konstanten sind final, aber ihre Variablen können dennoch geändert werden. Zum Beispiel können wir die Methode setPriority() verwenden, um die Priorität der Enum-Konstanten zu ändern. Wir werden dies in einem späteren Beispiel sehen.
  14. Da Enum-Konstanten final sind, können wir sie sicher mit == und der Methode equals() vergleichen. Beide haben dasselbe Ergebnis.

Java EnumSet, EnumMap, valueOf()

Nun, da wir die meisten Funktionen von Enum kennen, werfen wir einen Blick auf ein Java Enum-Beispielprogramm. Dann werden wir weitere Funktionen eines Enums kennenlernen.

package com.journaldev.enums;

import java.io.IOException;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Set;

public class JavaEnumExamples {

    public static void main(String[] args) throws IOException {

        usingEnumMethods();

        usingEnumValueOf();

        usingEnumValues();

        usingEnumInSwitch(ThreadStatesEnum.START);
        usingEnumInSwitch(ThreadStatesEnum.DEAD);

        usingEnumMap();

        usingEnumSet();

    }

    private static void usingEnumSet() {
        EnumSet enumSet = EnumSet.allOf(ThreadStatesEnum.class);
        for(ThreadStatesEnum tsenum : enumSet) {
            System.out.println("Using EnumSet, priority = " + tsenum.getPriority());
        }
    }

    private static void usingEnumMap() {
        EnumMap<ThreadStatesEnum, String> enumMap = new EnumMap<>(ThreadStatesEnum.class);
        enumMap.put(ThreadStatesEnum.START, "Thread ist gestartet");
        enumMap.put(ThreadStatesEnum.RUNNING, "Thread läuft");
        enumMap.put(ThreadStatesEnum.WAITING, "Thread wartet");
        enumMap.put(ThreadStatesEnum.DEAD, "Thread ist tot");

        Set keySet = enumMap.keySet();
        for(ThreadStatesEnum key : keySet) {
            System.out.println("key=" + key.toString() + ":: value=" + enumMap.get(key));
        }
    }

    private static void usingEnumInSwitch(ThreadStatesEnum th) {
        switch (th) {
            case START:
                System.out.println("START-Thread");
                break;
            case WAITING:
                System.out.println("WAITING-Thread");
                break;
            case RUNNING:
                System.out.println("RUNNING-Thread");
                break;
            case DEAD:
                System.out.println("DEAD-Thread");
        }
    }

    private static void usingEnumValues() {
        ThreadStatesEnum[] thArray = ThreadStatesEnum.values();

        for(ThreadStatesEnum th : thArray) {
            System.out.println(th.toString() + "::priority=" + th.getPriority());
        }
    }

    private static void usingEnumValueOf() {
        ThreadStatesEnum th = Enum.valueOf(ThreadStatesEnum.class, "START");
        System.out.println("th priority=" + th.getPriority());
    }

    private static void usingEnumMethods() throws IOException {
        ThreadStatesEnum thc = ThreadStatesEnum.DEAD;
        System.out.println("priority is:" + thc.getPriority());

        thc = ThreadStatesEnum.DEAD;
        System.out.println("Using overridden method." + thc.toString());

        thc = ThreadStatesEnum.START;
        System.out.println("Using overridden method." + thc.toString());
        thc.setPriority(10);
        System.out.println("Enum Constant variable changed priority value=" + thc.getPriority());
        thc.close();
    }

}

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren:

centron Managed Cloud Hosting in Deutschland

Mocking Void Methods mit EasyMock

Anleitung, JavaScript
Mocking Void Methods mit EasyMock Im Unit Testing ist Mocking eine essentielle Technik, die Entwicklern ermöglicht, das Verhalten komplexer Objekte zu simulieren. EasyMock ist ein beliebtes Framework zur Erstellung von…