Sök…


Introduktion

Java-enums (deklareras med hjälp av enum nyckelordet) är en kort syntax för stora mängder konstanter i en enda klass.

Syntax

  • [public / skyddad / privat] enum Enum_name {// Förklara ett nytt enum.
  • ENUM_CONSTANT_1 [, ENUM_CONSTANT_2 ...]; // Förklara enumkonstanterna. Detta måste vara den första raden inuti enum och bör separeras med komma, med en semikolon i slutet.
  • ENUM_CONSTANT_1 (param) [, ENUM_CONSTANT_2 (param) ...]; // Förklara enumkonstanter med parametrar. Parametertyperna måste matcha konstruktorn.
  • ENUM_CONSTANT_1 {...} [, ENUM_CONSTANT_2 {...} ...]; // Förklara enumkonstanter med åsidosatta metoder. Detta måste göras om enumet innehåller abstrakta metoder; alla sådana metoder måste implementeras.
  • ENUM_CONSTANT.name () // Returnerar en sträng med namnet på enumkonstanten.
  • ENUM_CONSTANT.ordinal () // Returnerar ordningen för denna uppräkningskonstant, dess position i sin enumdeklaration, där den initiala konstanten tilldelas en ordinal av noll.
  • Enum_name.values () // Returnerar en ny matris (av typen Enum_name []) som innehåller varje konstant i det enumet varje gång det kallas.
  • Enum_name.valueOf ("ENUM_CONSTANT") // Det inversa av ENUM_CONSTANT.name () - returnerar enumkonstanten med det givna namnet.
  • Enum.valueOf (Enum_name.class, "ENUM_CONSTANT") // En synonym till den föregående: Inverteringen av ENUM_CONSTANT.name () - returnerar enumkonstanten med det givna namnet.

Anmärkningar

begränsningar

Enums utökar alltid java.lang.Enum , så det är omöjligt för enum att utöka en klass. Men de kan implementera många gränssnitt.

tips och tricks

På grund av deras specialiserade representation finns det mer effektiva kartor och uppsättningar som kan användas med enums som nycklar. Dessa kommer ofta att gå snabbare än deras icke-specialiserade motsvarigheter.

Förklara och använda en grundläggande enum

Enum kan betraktas som syntaxsocker för en förseglad klass som endast instanseras ett antal gånger kända vid sammanställningstiden för att definiera en uppsättning konstanter.

Ett enkelt enum för att lista de olika säsongerna skulle förklaras på följande sätt:

public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

Även om enumkonstanterna inte nödvändigtvis behöver vara i all-caps, är det Java-konventionen att namnen på konstanter är helt versaler med ord som är separerade med understreck.


Du kan förklara en Enum i sin egen fil:

/**
 * This enum is declared in the Season.java file.
*/
public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

Men du kan också förklara det i en annan klass:

 public class Day {

    private Season season;

    public String getSeason() {
        return season.name();
    }

    public void setSeason(String season) {
        this.season = Season.valueOf(season);
    }

    /**
     * This enum is declared inside the Day.java file and 
     * cannot be accessed outside because it's declared as private.
     */
    private enum Season {
        WINTER,
        SPRING,
        SUMMER,
        FALL
    }

}

Slutligen kan du inte förklara en Enum i en metodkropp eller konstruktör:

public class Day {

    /**
     * Constructor
    */
    public Day() {
        // Illegal. Compilation error
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }
    }

    public void aSimpleMethod() {
        // Legal. You can declare a primitive (or an Object) inside a method. Compile!
        int primitiveInt = 42;

        // Illegal. Compilation error.
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }

        Season season = Season.SPRING;
    }
    
}

Duplicerade enumkonstanter är inte tillåtna:

public enum Season {
    WINTER,
    WINTER, //Compile Time Error : Duplicate Constants
    SPRING,
    SUMMER,
    FALL
} 

Varje konstant av enum är som standard public , static och final . Eftersom varje konstant är static kan de nås direkt med enum-namnet.

Enumkonstanter kan passeras runt som metodparametrar:

public static void display(Season s) {
    System.out.println(s.name());  // name() is a built-in method that gets the exact name of the enum constant
}

display(Season.WINTER);  // Prints out "WINTER"

Du kan få en mängd enumkonstanter med metoden values() . Värdena garanteras vara i deklarationsordning i den returnerade matrisen:

Season[] seasons = Season.values();

Obs: den här metoden fördelar en ny mängd värden varje gång den kallas.


För att iterera över enumkonstanterna:

public static void enumIterate() {
    for (Season s : Season.values()) {
        System.out.println(s.name());
    }
}

Du kan använda enums i ett switch uttalande:

public static void enumSwitchExample(Season s) {
    switch(s) {
        case WINTER:
            System.out.println("It's pretty cold");
            break;
        case SPRING:
            System.out.println("It's warming up");
            break;
        case SUMMER:
            System.out.println("It's pretty hot");
            break;
        case FALL:
            System.out.println("It's cooling down");
            break;
    }
}

Du kan också jämföra enumkonstanter med == :

Season.FALL == Season.WINTER    // false
Season.SPRING == Season.SPRING  // true

Ett annat sätt att jämföra enumkonstanter är att använda equals() som nedan, vilket anses vara dålig praxis eftersom du lätt kan falla i fallgrop enligt följande:

Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error

Även om uppsättningen av instanser i enum inte kan ändras vid körning, är själva instanserna inte i sig naturligt oföränderliga, eftersom enum kan, liksom någon annan klass, innehålla muterbara fält som visas nedan.

public enum MutableExample {
    A,
    B;

    private int count = 0;

    public void increment() {
        count++;
    }

    public void print() {
        System.out.println("The count of " + name() + " is " + count);
    }
}

// Usage:
MutableExample.A.print();       // Outputs 0
MutableExample.A.increment();
MutableExample.A.print();       // Outputs 1 -- we've changed a field   
MutableExample.B.print();       // Outputs 0 -- another instance remains unchanged

En bra praxis är emellertid att göra enum instanser oföränderliga, dvs när de antingen inte har några ytterligare fält eller alla sådana fält markeras som final och själva är oföränderliga. Detta kommer att säkerställa att en enum en enum kommer att läcka något minne och att det är säkert att använda sina instanser över alla trådar.


Enums implementerar implicit Serializable och Comparable eftersom Enum klassen gör:

public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable

Enums med konstruktörer

enum kan inte ha en offentlig konstruktör; privata konstruktörer är dock acceptabla (konstruktörer för enums är som standard paket-privata ):

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25); // usual names for US coins
    // note that the above parentheses and the constructor arguments match
    private int value;

    Coin(int value) { 
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

Det rekommenderas att du håller alla fält privata och tillhandahåller getter-metoder, eftersom det finns ett begränsat antal instanser för enum.


Om du istället skulle implementera en Enum som class skulle det se ut så här:

public class Coin<T extends Coin<T>> implements Comparable<T>, Serializable{
    public static final Coin PENNY = new Coin(1);
    public static final Coin NICKEL = new Coin(5);
    public static final Coin DIME = new Coin(10);
    public static final Coin QUARTER = new Coin(25);

    private int value;

    private Coin(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

Enumkonstanter är tekniskt muterbara, så en setter kan läggas till för att ändra den interna strukturen i enumkonstant. Detta anses dock som mycket dålig praxis och bör undvikas.

Bästa praxis är att göra Enum-fält oföränderliga, med final :

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int value;

    Coin(int value){ 
        this.value = value;
    }

    ...

}

Du kan definiera flera konstruktörer i samma enum. När du gör det bestämmer de argument du skickar i din enumdeklaration vilken konstruktör som heter:

public enum Coin {
    PENNY(1, true), NICKEL(5, false), DIME(10), QUARTER(25);

    private final int value;
    private final boolean isCopperColored;

    Coin(int value){
        this(value, false);
    }

    Coin(int value, boolean isCopperColored){ 
        this.value = value;
        this.isCopperColored = isCopperColored;
    }

    ...

}

Obs: Alla icke-primitiva enum-fält bör implementera Serializable eftersom Enum klassen gör det.

Med hjälp av metoder och statiska block

Enum kan innehålla en metod, precis som alla klasser. För att se hur detta fungerar, förklarar vi ett enum som detta:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;
}

Låt oss ha en metod som returnerar enum i motsatt riktning:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;

    public Direction getOpposite(){
        switch (this){
            case NORTH:
                return SOUTH;               
            case SOUTH:
                return NORTH;                
            case WEST:
                return EAST; 
            case EAST:
                return WEST;  
            default: //This will never happen
                return null;
        }
    }
}

Detta kan förbättras ytterligare genom användning av fält och statiska initialiseringsblock:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;
    
    private Direction opposite;
    
    public Direction getOpposite(){
        return opposite;
    }
    
    static {
        NORTH.opposite = SOUTH;
        SOUTH.opposite = NORTH;
        WEST.opposite = EAST;
        EAST.opposite = WEST;
    }
}

I det här exemplet lagras motsatt riktning i ett opposite som statiskt initialiseras första gången en Direction används. I detta specifika fall (eftersom NORTH refererar SOUTH och omvänt), kan vi inte använda Enums med konstruktörer här (Konstruktorer NORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST) skulle vara mer elegant och skulle tillåta opposite till förklaras final , men skulle vara självreferensiellt och därför inte tillåtet).

Implementerar gränssnitt

Detta är en enum som också är en kallbar funktion som testar String mot förkompilerade reguljära uttrycksmönster.

import java.util.function.Predicate;
import java.util.regex.Pattern;

enum RegEx implements Predicate<String> {
    UPPER("[A-Z]+"), LOWER("[a-z]+"), NUMERIC("[+-]?[0-9]+");

    private final Pattern pattern;

    private RegEx(final String pattern) {
        this.pattern = Pattern.compile(pattern);
    }

    @Override 
    public boolean test(final String input) {
        return this.pattern.matcher(input).matches();
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(RegEx.UPPER.test("ABC"));
        System.out.println(RegEx.LOWER.test("abc"));
        System.out.println(RegEx.NUMERIC.test("+111"));
    }
}

Varje medlem i enum kan också implementera metoden:

import java.util.function.Predicate;

enum Acceptor implements Predicate<String> {
    NULL {
        @Override
        public boolean test(String s) { return s == null; }
    },
    EMPTY {
        @Override
        public boolean test(String s) { return s.equals(""); }
    },
    NULL_OR_EMPTY {
        @Override
        public boolean test(String s) { return NULL.test(s) || EMPTY.test(s); }
    };
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Acceptor.NULL.test(null));  // true
        System.out.println(Acceptor.EMPTY.test(""));   // true
        System.out.println(Acceptor.NULL_OR_EMPTY.test(" ")); // false
    }
}

Enum polymorfism mönster

När en metod måste acceptera en "utsträckbar" uppsättning av enum , kan programmeraren tillämpa polymorfism som på en normal class genom att skapa ett gränssnitt som kommer att användas oavsett var enum ska användas:

public interface ExtensibleEnum {
    String name();
}

På så sätt kan alla enum taggade av (implementera) gränssnittet användas som en parameter, vilket gör att programmeraren kan skapa en variabel mängd enum som kommer att accepteras av metoden. Detta kan vara användbart, till exempel i API: er där det finns en standard (omodifierbar) enum och användaren av dessa API: er vill "utöka" enum med fler värden.

En uppsättning standardvärden för enum kan definieras enligt följande:

public enum DefaultValues implements ExtensibleEnum {
    VALUE_ONE, VALUE_TWO;
}

Ytterligare värden kan sedan definieras så här:

public enum ExtendedValues implements ExtensibleEnum {
    VALUE_THREE, VALUE_FOUR;
}

Exempel som visar hur man använder enums - notera hur printEnum() accepterar värden från båda enum :

private void printEnum(ExtensibleEnum val) {
    System.out.println(val.name());
}  

printEnum(DefaultValues.VALUE_ONE);    // VALUE_ONE
printEnum(DefaultValues.VALUE_TWO);    // VALUE_TWO
printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE
printEnum(ExtendedValues.VALUE_FOUR);  // VALUE_FOUR

Obs: Det här mönstret hindrar inte dig från att omdefiniera enumvärden, som redan är definierade i ett enum, i ett annat enum. Dessa enumvärden skulle då vara olika. Det är inte heller möjligt att använda switch-on-enum eftersom allt vi har är gränssnittet, inte the real enum .

Enums med abstrakta metoder

Enums kan definiera abstrakta metoder som varje enum måste implementera.

enum Action {
    DODGE {
        public boolean execute(Player player) {
            return player.isAttacking();
        }
    },
    ATTACK {
        public boolean execute(Player player) {
            return player.hasWeapon();
        }
    },
    JUMP {
        public boolean execute(Player player) {
            return player.getCoordinates().equals(new Coordinates(0, 0));
        }
    };

    public abstract boolean execute(Player player);
}

Detta gör det möjligt för varje enummedlem att definiera sitt eget beteende för en given operation utan att behöva slå på typer i en metod i toppnivådefinitionen.

Observera att detta mönster är en kort form av vad som vanligtvis uppnås med polymorfism och / eller implementeringsgränssnitt.

Dokumentera enums

enum är inte alltid tydligt för att förstås. För att dokumentera enum använder du standard javadoc:

/**
 * United States coins
 */
public enum Coins {
    
    /**
     * One-cent coin, commonly known as a penny, 
     * is a unit of currency equaling one-hundredth 
     * of a United States dollar
     */
    PENNY(1),

    /**
     * A nickel is a five-cent coin equaling 
     * five-hundredth of a United States dollar
     */        
    NICKEL(5),

    /**
     * The dime is a ten-cent coin refers to 
     * one tenth of a United States dollar
     */        
    DIME(10),

    /**
     * The quarter is a US coin worth 25 cents, 
     * one-fourth of a United States dollar
     */        
    QUARTER(25);

    private int value;

    Coins(int value){ 
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

Få värden på enum

Varje enumklass innehåller en implicit statisk metod som heter values() . Denna metod returnerar en matris som innehåller alla värden på det enumet. Du kan använda den här metoden för att iterera över värdena. Det är dock viktigt att notera att denna metod returnerar en ny matris varje gång den kallas.

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    
    /**
    * Print out all the values in this enum.
    */
    public static void printAllDays() {
        for(Day day : Day.values()) {
            System.out.println(day.name());
        }
    }
}

Om du behöver en Set du använda EnumSet.allOf(Day.class) också.

Enum som en begränsad typparameter

När du skriver en klass med generik i java är det möjligt att se till att typparametern är en enum. Eftersom alla enums utökar klassen Enum kan följande syntax användas.

public class Holder<T extends Enum<T>> {
    public final T value;

    public Holder(T init) {
        this.value = init;
    }
}

I detta exempel måste typen T vara en enum.

Få enum konstant med namn

Säg att vi har enum DayOfWeek :

enum DayOfWeek {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

Enum sammanställs med en inbyggd statisk valueOf() -metod som kan användas för att slå upp en konstant med namnet:

String dayName = DayOfWeek.SUNDAY.name();
assert dayName.equals("SUNDAY");

DayOfWeek day = DayOfWeek.valueOf(dayName);
assert day == DayOfWeek.SUNDAY;

Detta är också möjligt med en dynamisk enumtyp:

Class<DayOfWeek> enumType = DayOfWeek.class;
DayOfWeek day = Enum.valueOf(enumType, "SUNDAY");
assert day == DayOfWeek.SUNDAY;

Båda dessa valueOf() kommer att kasta en IllegalArgumentException om den angivna enum inte har en konstant med ett matchande namn.

Guava-biblioteket tillhandahåller en Enums.getIfPresent() som returnerar ett Guava- Optional att eliminera uttrycklig hantering av undantag:

DayOfWeek defaultDay = DayOfWeek.SUNDAY;
DayOfWeek day = Enums.valueOf(DayOfWeek.class, "INVALID").or(defaultDay);
assert day == DayOfWeek.SUNDAY;

Implementera Singleton-mönster med en en-element enum

Enumkonstanter instanseras när en enum refereras för första gången. Därför gör det möjligt att implementera Singleton mjukvarudesignmönster med en en-element enum.

public enum Attendant {

    INSTANCE;

    private Attendant() {
        // perform some initialization routine
    }

    public void sayHello() {
        System.out.println("Hello!");
    }
}


public class Main {

    public static void main(String... args) {
        Attendant.INSTANCE.sayHello();// instantiated at this point
    }
}

Enligt "Effektiv Java" -bok av Joshua Bloch är en en-element enum det bästa sättet att implementera en singleton. Detta tillvägagångssätt har följande fördelar:

  • gängesäkerhet
  • garanti för enstaka instans
  • out-of-the-box serialisering

Och som visas i avsnittet implementerar gränssnittet kan detta singleton också implementera ett eller flera gränssnitt.

Enum med egenskaper (fält)

Om vi vill använda enum med mer information och inte bara som konstanta värden, och vi vill kunna jämföra två enum.

Tänk på följande exempel:

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int value;

    Coin(int value){
        this.value = value;
    }

    public boolean isGreaterThan(Coin other){
        return this.value > other.value;
    }

}

Här definierade vi en Enum heter Coin som representerar dess värde. Med metoden är isGreaterThan vi jämföra två enum :

Coin penny = Coin.PENNY;
Coin dime = Coin.DIME;

System.out.println(penny.isGreaterThan(dime)); // prints: false
System.out.println(dime.isGreaterThan(penny)); // prints: true

Konvertera enum till String

Ibland vill du konvertera din enum till en sträng, det finns två sätt att göra det.

Antag att vi har:

public enum Fruit {
    APPLE, ORANGE, STRAWBERRY, BANANA, LEMON, GRAPE_FRUIT;
}

Så hur konverterar vi något som Fruit.APPLE till "APPLE" ?


Konvertera med name()

name() är en intern metod i enum som återför String representation av enum, retur String representerar exakt hur enum värdet definierades.

Till exempel:

System.out.println(Fruit.BANANA.name());      // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.name()); // "GRAPE_FRUIT"

Konvertera med toString()

toString() är som standard åsidosatt för att ha samma beteende som name()

toString() är dock troligtvis åsidosatt av utvecklare för att göra det att skriva ut en mer användarvänlig String

Använd inte toString() om du vill kontrollera din kod, name() är mycket mer stabilt för det. toString() bara toString() när du ska mata ut värdet till loggar eller stdout eller något

Som standard:

System.out.println(Fruit.BANANA.toString());      // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "GRAPE_FRUIT"

Exempel på att åsidosättas

System.out.println(Fruit.BANANA.toString());      // "Banana"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "Grape Fruit"

Enum konstant specifik kropp

I en enum är det möjligt att definiera ett specifikt beteende för en speciell konstanten för enum som åsidosätter standardbeteende enum , denna teknik är känd som konstant specifik kropp.

Anta att tre pianostudenter - John, Ben och Luke - definieras i ett enum heter PianoClass enligt följande:

    enum PianoClass {
    JOHN, BEN, LUKE;
        public String getSex() {
            return "Male";
        }
        public String getLevel() {
            return "Beginner";
        }
    }

Och en dag anländer två andra studenter - Rita och Tom - med en kön (kvinna) och nivå (mellanliggande) som inte matchar de tidigare:

    enum PianoClass2 {
    JOHN, BEN, LUKE, RITA, TOM;
        public String getSex() {
            return "Male"; // issue, Rita is a female
        }
        public String getLevel() {
            return "Beginner"; // issue, Tom is an intermediate student
        }
    }

så att helt enkelt inte lägga till de nya studenterna till den ständiga deklarationen, enligt följande, inte är korrekt:

PianoClass2 tom = PianoClass2.TOM;
PianoClass2 rita = PianoClass2.RITA;
System.out.println(tom.getLevel()); // prints Beginner -> wrong Tom's not a beginner
System.out.println(rita.getSex()); // prints Male -> wrong Rita's not a male

Det är möjligt att definiera ett specifikt beteende för varje konstant Rita och Tom, som åsidosätter PianoClass2 standardbeteendet på följande sätt:

enum PianoClass3 {
    JOHN, BEN, LUKE,
    RITA {
        @Override
        public String getSex() {
            return "Female";
        }
    },
    TOM {
        @Override
        public String getLevel() {
            return "Intermediate";
        }
    };
    public String getSex() {
        return "Male";
    }
    public String getLevel() {
        return "Beginner";
    }
}

och nu är Toms nivå och Ritas kön som de borde vara:

PianoClass3 tom = PianoClass3.TOM;
PianoClass3 rita = PianoClass3.RITA;
System.out.println(tom.getLevel()); // prints Intermediate
System.out.println(rita.getSex()); // prints Female

Ett annat sätt att definiera innehållsspecifik kropp är att använda konstruktör, till exempel:

enum Friend {
    MAT("Male"),
    JOHN("Male"),
    JANE("Female");
    
    private String gender;

    Friend(String gender) {
        this.gender = gender;
    }

    public String getGender() {
        return this.gender;
    }
}

och användning:

Friend mat = Friend.MAT;
Friend john = Friend.JOHN;
Friend jane = Friend.JANE;
System.out.println(mat.getGender());     // Male
System.out.println(john.getGender());    // Male
System.out.println(jane.getGender());    // Female

Noll instans enum

enum Util {
    /* No instances */;

    public static int clamp(int min, int max, int i) {
        return Math.min(Math.max(i, min), max);
    }

    // other utility methods...
}

Precis som enum kan användas för singletons (1 instansklasser), kan den användas för verktygsklasser (0 instansklasser). Se bara till att avsluta (tom) listan över enumkonstanter med en ; .

Se frågan Zero instans enum vs privata konstruktörer för att förhindra instans för en diskussion om pro och con jämfört med privata konstruktörer.

Enums med statiska fält

Om din enum-klass måste ha statiska fält, kom ihåg att de skapas efter enum-värdena själva. Det betyder att följande kod kommer att resultera i en NullPointerException :

enum Example {
    ONE(1), TWO(2);

    static Map<String, Integer> integers = new HashMap<>();

    private Example(int value) {
        integers.put(this.name(), value);
    }
}

Ett möjligt sätt att fixa detta:

enum Example {
    ONE(1), TWO(2);

    static Map<String, Integer> integers;

    private Example(int value) {
        putValue(this.name(), value);
    }

    private static void putValue(String name, int value) {
        if (integers == null)
            integers = new HashMap<>();
        integers.put(name, value);
    }
}

Initiera inte det statiska fältet:

enum Example {
    ONE(1), TWO(2);

    // after initialisisation integers is null!!
    static Map<String, Integer> integers = null;

    private Example(int value) {
        putValue(this.name(), value);
    }

    private static void putValue(String name, int value) {
        if (integers == null)
            integers = new HashMap<>();
        integers.put(name, value);
    }
    // !!this may lead to null poiner exception!!
    public int getValue(){
        return (Example.integers.get(this.name()));
    }
}

initialisisation:

  • skapa enumvärden
    • som biverkning putValue () kallas som initialiserar heltal
  • de statiska värdena är inställda
    • heltal = null; // körs efter enums så innehållet i heltal går förlorat

Jämför och innehåller för Enum-värden

Enums innehåller endast konstanter och kan jämföras direkt med == . Så behövs endast referens check, ingen anledning att använda .equals metod. Om .equals används felaktigt kan dessutom höja NullPointerException medan det inte är fallet med == check.

enum Day {
    GOOD, AVERAGE, WORST;
}

public class Test {

    public static void main(String[] args) {
        Day day = null;

        if (day.equals(Day.GOOD)) {//NullPointerException!
            System.out.println("Good Day!");
        }

        if (day == Day.GOOD) {//Always use == to compare enum
            System.out.println("Good Day!");
        }

    }
}

För att gruppera, komplettera, variera enumvärdena vi har EnumSet klass som innehåller olika metoder.

  • EnumSet#range : För att få en deluppsättning av enum efter intervall definierat av två slutpunkter

  • EnumSet#of : Uppsättning av specifika enum utan någon räckvidd. Flera överbelastad of metoder finns.

  • EnumSet#complementOf : Uppsättning av enum som är komplement till enumvärden som anges i metodparametern

    enum Page {
       A1, A2, A3, A4, A5, A6, A7, A8, A9, A10
    }
    
    public class Test {
    
      public static void main(String[] args) {
          EnumSet<Page> range = EnumSet.range(Page.A1, Page.A5);
    
          if (range.contains(Page.A4)) {
              System.out.println("Range contains A4");
          }
    
          EnumSet<Page> of = EnumSet.of(Page.A1, Page.A5, Page.A3);
    
          if (of.contains(Page.A1)) {
              System.out.println("Of contains A1");
          }
      }
    }
    


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow