Jelenlegi hely

14. Felsorolás típus

A felsorolás típus egy olyan típus, melynek megengedett értékei fix konstansokból állnak. Javában a felsorolás típust enum szóval definiáljuk. Pl. a hét napjait így definiálhatjuk:

enum Days {
  VASARNAP, HETFO, KEDD, SZERDA, CSUTORTOK, PENTEK, SZOMBAT};
}

Vegyük észre, hogy konvencionálisan a nevek a felsorolás típusnál nagy betűkkel írandók, így a kód olvasásánál könnyen felismerhetők a konstansok.
Bármikor használhatunk felsorolás típust, ha szükségünk van kötött konstans értékekre. Ez magában foglalja a természetes felsorolás típusokat, mint a Naprendszer bolygói, a hét napjai, kártyapakli lapjainak neve/értéke és minden olyan esetet, ahol az összes lehetséges értéket tudjuk a fordításkor.

A Java programozási nyelv felsorolás típusa sokkal hatékonyabb, mint más nyelvekben szereplő megfelelői, melyek csak nevesített egész számok. Az enum deklaráció egy osztályt definiál, úgynevezett enum típust, melynek legfontosabb jellemzői a következők:

  • Beszédesebbek az egyszerű literáloknál
  • Típusbiztosak
  • Saját névterük van
  • Érdemes switch-case szerkezetben felsorolási típus alapján szervezni
  • Van egy statikus values metódusuk, mely egy tömböt ad vissza, melyben a típus értékei szerepelnek deklarálási sorrendben. Ez a módszer pl. for-each ciklussal nagyon hasznos.
  • Tartalmazhat metódusokat, adattagokat, implementálhat interfészeket stb.
  • Minden Object metódust implementálnak. Összehasonlíthatók és szerializálhatók.

A következő példában a Planet egy felsorolás típus, mely a Naprendszer bolygóit jeleníti meg. A bolygónak van egy konstans tömeg és sugár paramétere. Minden konstanst tömeggel és sugárral deklarálnak, melyet átadnak a konstruktornak a létrehozáskor. Vegyük észre, hogy a felsorolás típus konstruktora értelemszerűen privát. Ha megpróbálunk egy publikus konstruktort létrehozni a felsorolás típusnak, akkor a fordító hibaüzenetet fog visszaadni.

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7),
    PLUTO   (1.27e+22,  1.137e6);

    private final double mass;   //in kilograms
    private final double radius; //in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    public double mass()   { return mass; }
    public double radius() { return radius; }
    public static final double G = 6.67300E-11;
    public double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

A bolygónak az értékei mellett metódusai is vannak, melyeken keresztül kinyerhető a felszíni gravitáció és egy tárgy súlya minden bolygón. A következő példaprogram egy ember Földön mért súlya alapján kiszámolja, majd kiírja ugyanennek az embernek a súlyát minden bolygón.

public static void main(String[] args) {
    double earthWeight = Double.parseDouble(args[0]);
    double mass = earthWeight/EARTH.surfaceGravity();
    for (Planet p : Planet.values()) {
        System.out.printf("Your weight on %s is %f%n",
                          p, p.surfaceWeight(mass));
    }
}

A kimenet:

$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
Your weight on EARTH is 175.000000
Your weight on MARS is 66.279007
Your weight on JUPITER is 442.847567
Your weight on SATURN is 186.552719
Your weight on URANUS is 158.397260
Your weight on NEPTUNE is 199.207413
Your weight on PLUTO is 11.703031

Csak egyetlen megkötése van a felsorolás típusnak: habár a felsorolás típusok osztályok, nem definiálható hierarchia számukra. Más szavakkal: nem lehet leszármazottja a felsorolási típusnak.

Végezetül a java.util csomag tartalmaz két speciális Set és Map implementációt, mely támogatja a felsorolás típusokat, az EnumSet-et és az EnumMap-et.

Ellenőrző kérdések

  • Mikor érdemes felsorolás típust alkalmazni?
  • Milyen korlátozások vannak a felsorolás típusra más osztályokhoz képest?