Inleiding

Er bestaat in Java een bijzondere vorm van een klasse, namelijk de opsomming of de enumeration. Van deze soort klasse zijn er een welbepaald aantal vaste instanties beschikbaar. Ze worden als statische eigenschappen van de klasse opgesomd, vandaar de naam enumeration of opsomming. Zelf kunnen we geen nieuwe instanties maken.

Stel dat we voor onze bestellingssoftware een welbepaald aantal toestanden van een bestelling willen bijhouden. We gaan hierbij elke toestand of status als een object voorstellen. We kunnen dan de opsomming OrderStatus als volgt definiëren:

public enum OrderStatus {
    PROCESSING,
    ORDERED,
    READY,
    IN_TRANSIT,
    DELIVERED;
}

Omdat zij constanten zijn, worden de namen van een enum zijn velden in hoofdletters met laag streepje als spatie geschreven.

De syntax voor de definitie van een opsomming lijkt op die van een klasse. Het woord class wordt hierbij vervangen door enum en verder worden de toegelaten instanties opgesomd.

Deze opsomming bepaalt de naam en het volgnummer van de instantie en construeert tevens het object. Het is analoog aan de declaratie en constructie van static members van een klasse. Enums worden trouwens naar verwezen op dezelfde manier als een static members van een klasse:

OrderStatus status = OrderStatus.PROCESSING;

Iedere opsomming is impliciet een subklasse van de klasse Enum en erft dan ook de methoden van de klasse over. Zo kan de naam en het volgnummer van ieder instantie opgevraagd worden met de overgeërfde methoden name() en ordinal().

toString( )

Een enum krijgt automatisch een toString() methode tijdens compilatie. De standaard toString() methode van een enum geeft de naam terug van de gegeven enum instantie.

Bijgevolg, als je een enum print, wordt de naam van die enum instantie geprint (wanneer je een object probeert te printen wordt zijn toString() methode achter de schermen aangeroepen)

System.out.println(OrderStatus.READY)          // Prints 'READY'

Merk op dat we hetzelfde resultaat krijgen als wij .name() gebruiken

System.out.println(OrderStatus.READY.name());  // Prints 'READY'

If statements

Je kan enums gebruiken om variabelen te controleren:

if(status == OrderStatus.READY){
    ...
    // Perform logic to send out for delivery
    ...
}

Switch

Als jouw enum veel constanten bevat en daarom een uitgebreid if-statement structuur nodig zou hebben, is het soms een goede idee om in plaats van if-statements een switch-statement te gebruiken:

        switch (status) {
            case ORDERED:
                processOrder();
                break;
            case PROCESSING:
                makeOrderReadyForShipping();
                break;
            case READY:
                shipOrderItems();
                break;
            case IN_TRANSIT:
                deliverItems();
                break;
            case DELIVERED:
                askForRating();
                break;
            default:
                message = null;
        }

We kunnen dit type nu als volgt gebruiken:

public class OrderApp {
    public static void main(String[] args) {
        OrderStatus status = OrderStatus.READY;
        printStatus(status);
        status = OrderStatus.IN_TRANSIT;
        printStatus(status);
        status = OrderStatus.DELIVERED;
        printStatus(status);
    }

    private static void printStatus(OrderStatus status) {
        String message;
        switch (status) {
            case ORDERED:
                message = "Your order has been confirmed";
                break;
            case PROCESSING:
                message = "Your order is being processed";
                break;
            case READY:
                message = "Your order is ready for pick-up";
                break;
            case IN_TRANSIT:
                message = "Your order has been shipped and is on its way";
                break;
            case DELIVERED:
                message = "Your order has arrived";
                break;
            default:
                message = null;
        }
        System.out.printf("%d. %s: %s%n", status.ordinal(), status.name(), message);
    }
}

Verzameling van de mogelijke instanties

Met de statische .values() methode die elke enum klasse krijgt, kunnen we een array opvragen met daarin alle mogelijke instanties. Met andere woorden, .values() geeft een lijst van de enumeratie constanten terug, gesorteerd volgens de volgorde opgegeven in de definitie.

Dit maakt het mogelijk om op een simpele manier doorheen alle enum constanten te lussen:

public enum ChemicalElement {
    H,
    HE,
    LI,
    // ...
    LR;
}
        for (ChemicalElement el : ChemicalElement.values()) {
            System.out.println(el);
        }

Enum opvragen adhv zijn naam

Met .valueOf() kunnen we een String gebruiken om een opsommingstype, waarmee die String overeenkomt met zijn naam, terug te krijgen

ChemicalElement helium = ChemicalElement.valueOf("HE");

Tip: Importeer jouw enum met een static import

Wens je alleen de naam van jouw enum constanten te gebruiken, in plaats van steeds eerst de naam van de enum klasse raad te plegen? Dan dien je gebruik te maken van een static import. Dit kan heel handig zijn als je waarden van

import static ChemicalElement.*
...
ChemicalElement helium = HE;
ChemicalElement lithium = LI;
...