Posso impostare il valore iniziale enum in Java?


194

Uso l'enum per creare alcune costanti:

enum ids {OPEN, CLOSE};

il valore APERTO è zero, ma lo voglio come 100. È possibile?


@ScottF Vuoi usare enums?
Anish B.

Nella risposta in alto c'è una definizione enum. Vorrei un esempio di come quell'enum definito sarebbe stato usato nel codice. Ad esempio, come verrà utilizzato il ctor definito per creare un'istanza enum con un valore intero specifico.
ScottF,

@ScottF se fossi in te, invece di impostare una taglia su questo post, preferirei pubblicare una domanda completamente nuova ..... o, leggere la documentazione su enum. Sembra che tu abbia bisogno di afferrare alcune conoscenze di base al riguardo;)
Lealceldeiro,

enum ids {OPEN = 100, CLOSE};?
Oscar

Risposte:


307

Gli enum Java non sono come gli enum C o C ++, che sono in realtà solo etichette per numeri interi.

Gli enum Java sono implementati più come le classi e possono anche avere più attributi.

public enum Ids {
    OPEN(100), CLOSE(200);

    private final int id;
    Ids(int id) { this.id = id; }
    public int getValue() { return id; }
}

La grande differenza è che sono sicuri per il tipo che significa che non devi preoccuparti di assegnare un enum COLOR a una variabile SIZE.

Vedi http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html per ulteriori informazioni.


Sulla base della tua affermazione, la migliore pratica usando java per creare un enum di numeri interi sequenziali (simile a un enum C ++), per un indice in un array o qualcosa del genere, sarebbe quella di scrivere: enum Ids {NAME (0), AGE (1 ), ALTEZZA (2), PESO (3); } Grazie, -bn
bn.

Forse, e specialmente se mai serializzi i valori integrali da qualche parte.
Lavinio,

1
puoi per favore dire come usare questo enum in una funzione?
Bugs Happen

2
È pigro degli standard Java per non consentire l'impostazione di un valore per un enum. Almeno c # consente questo AND è sicuro per i tipi.
fabbro

2
FWIW, C ++ 11 ora ha un tipo sicuro enum class.
phoenix,

93

Sì. È possibile passare i valori numerici al costruttore per l'enum, in questo modo:

enum Ids {
  OPEN(100),
  CLOSE(200);

  private int value;    

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

  public int getValue() {
    return value;
  }
}

Consultare la Guida linguistica di Sun Java per ulteriori informazioni.


Freddo. È possibile mescolare? Vale a dire assegnare numeri solo ai valori Enum scelti.
Federico Nord,

il modificatore privato è ridondante per i costruttori di enum
Nino van Hooff,

@FrederickNord - Sicuro. Basta aggiungere un secondo costruttore privato senza argomenti che si inizializza valuesu uno (diciamo) zero. Quindi includere (diciamo) DANCEnell'elenco dei valori.
Stephen C,

15

che ne dici di usare in questo modo:

public enum HL_COLORS{
          YELLOW,
          ORANGE;

          public int getColorValue() {
              switch (this) {
            case YELLOW:
                return 0xffffff00;
            case ORANGE:
                return 0xffffa500;    
            default://YELLOW
                return 0xffffff00;
            }
          }
}

c'è solo un metodo ..

puoi usare il metodo statico e passare l'Enum come parametro come:

public enum HL_COLORS{
          YELLOW,
          ORANGE;

          public static int getColorValue(HL_COLORS hl) {
              switch (hl) {
            case YELLOW:
                return 0xffffff00;
            case ORANGE:
                return 0xffffa500;    
            default://YELLOW
                return 0xffffff00;
            }
          }

Si noti che questi due modi utilizzano meno memoria e più unità di processo. Non dico che questo è il modo migliore ma è solo un altro approccio.


1
Perché è getColorValue()sincronizzato nel secondo esempio?
josaphatv,

@josaphatv Tutte le funzionalità del secondo esempio sono statiche, non cambiano mai. Potresti volerlo HL_COLORS.getColorValue(HL_COLORS.YELLOW);senza inizializzare l'enum.
Mazunki,

11

Se si usano tipi di enum molto grandi, seguire può essere utile;

public enum deneme {

    UPDATE, UPDATE_FAILED;

    private static Map<Integer, deneme> ss = new TreeMap<Integer,deneme>();
    private static final int START_VALUE = 100;
    private int value;

    static {
        for(int i=0;i<values().length;i++)
        {
            values()[i].value = START_VALUE + i;
            ss.put(values()[i].value, values()[i]);
        }
    }

    public static deneme fromInt(int i) {
        return ss.get(i);
    }

    public int value() {
    return value;
    }
}

7

Se vuoi emulare enum di C / C ++ (base num e nexts incrementals):

enum ids {
    OPEN, CLOSE;
    //
    private static final int BASE_ORDINAL = 100;
    public int getCode() {
        return ordinal() + BASE_ORDINAL;
    }
};

public class TestEnum {
    public static void main (String... args){
        for (ids i : new ids[] { ids.OPEN, ids.CLOSE }) {
            System.out.println(i.toString() + " " + 
                i.ordinal() + " " + 
                i.getCode());
        }
    }
}
OPEN 0 100
CLOSE 1 101

4

La funzione ordinal () restituisce la posizione relativa dell'identificatore nell'enum. Puoi usarlo per ottenere l'indicizzazione automatica con un offset, come con un enum di tipo C.

Esempio:

public class TestEnum {
    enum ids {
        OPEN,
        CLOSE,
        OTHER;

        public final int value = 100 + ordinal();
    };

    public static void main(String arg[]) {
        System.out.println("OPEN:  " + ids.OPEN.value);
        System.out.println("CLOSE: " + ids.CLOSE.value);
        System.out.println("OTHER: " + ids.OTHER.value);
    }
};

Fornisce l'output:

OPEN:  100
CLOSE: 101
OTHER: 102

Modifica: ho appena realizzato che questo è molto simile alla risposta di Ggrandes , ma lo lascerò qui perché è molto pulito e il più vicino possibile a un enum in stile C.


Nell'esempio prendi un enum e ottieni un int. Puoi mostrare il contrario, prendere un int e finire con un enum (senza un caso switch esplicito per ogni valore?)
ScottF

Secondo la domanda, credo che questa sia la risposta più adatta. Qui abbiamo modificato l'indice predefinito di enum per iniziare da 100 senza definire una nuova variabile e assegnarle tramite il costruttore.
Rahul Jain,

@RahulJain Preferirei usare la risposta accettata. Mi sembra più pulito.
Lealceldeiro,

1

@scottf

Un enum è come un Singleton. La JVM crea l'istanza.

Se lo creassi da solo con le classi, potrebbe essere così

public static class MyEnum {

    final public static MyEnum ONE;
    final public static MyEnum TWO;

    static {
        ONE = new MyEnum("1");
        TWO = new MyEnum("2");
    }

    final String enumValue;

    private MyEnum(String value){
        enumValue = value;    
    }

    @Override
    public String toString(){
        return enumValue;
    }


}

E potrebbe essere usato così:

public class HelloWorld{

   public static class MyEnum {

       final public static MyEnum ONE;
       final public static MyEnum TWO;

       static {
          ONE = new MyEnum("1");
          TWO = new MyEnum("2");
       }

       final String enumValue;

       private MyEnum(String value){
           enumValue = value;    
       }

       @Override
       public String toString(){
           return enumValue;
       }


   }

    public static void main(String []args){

       System.out.println(MyEnum.ONE);
       System.out.println(MyEnum.TWO);

       System.out.println(MyEnum.ONE == MyEnum.ONE);

       System.out.println("Hello World");
    }
}

0
 public class MyClass {
    public static void main(String args[]) {
     Ids id1 = Ids.OPEN;
     System.out.println(id1.getValue());
    }
}

enum Ids {
    OPEN(100), CLOSE(200);

    private final int id;
    Ids(int id) { this.id = id; }
    public int getValue() { return id; }
}

@scottf, probabilmente sei confuso a causa del costruttore definito in ENUM.

Lascia che te lo spieghi.

Quando class loadercarica enumclasse, enumviene chiamato anche dal costruttore. Su cosa!! Sì, si chiama OPENe close. Con quali valori 100per OPENe 200perclose

Posso avere un valore diverso?

Sì,

public class MyClass {
    public static void main(String args[]) {
     Ids id1 = Ids.OPEN;
     id1.setValue(2);
     System.out.println(id1.getValue());
    }
}

enum Ids {
    OPEN(100), CLOSE(200);

    private int id;
    Ids(int id) { this.id = id; }
    public int getValue() { return id; }
    public void setValue(int value) { id = value; }
}

Ma è una cattiva pratica. enumè usato per rappresentare constantssimili days of week, colors in rainbowcioè un piccolo gruppo di costanti predefinite.


0

Penso che tu sia confuso guardando gli enumeratori C ++. Gli enumeratori Java sono diversi.

Questo sarebbe il codice se sei abituato alle enumerazioni C / C ++:

public class TestEnum {
enum ids {
    OPEN,
    CLOSE,
    OTHER;

    public final int value = 100 + ordinal();
};

public static void main(String arg[]) {
    System.out.println("OPEN:  " + ids.OPEN.value);
    System.out.println("CLOSE: " + ids.CLOSE.value);
    System.out.println("OTHER: " + ids.OTHER.value);
}
};
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.