Posso definir o valor inicial de enum em Java?


194

Eu uso o enum para fazer algumas constantes:

enum ids {OPEN, CLOSE};

o valor OPEN é zero, mas eu quero como 100. É possível?


@ScottF Você quer usar enums?
— Anish B.

Na resposta superior, há uma definição de enumeração. Gostaria de um exemplo de como essa enumeração definida seria usada no código. Por exemplo, como o ctor definido seria usado para criar uma instância de enum com um valor inteiro específico.
— ScottF

@ ScottF se eu fosse você, em vez de definir uma recompensa neste post, prefiro postar uma pergunta completamente nova ..... ou ler a documentação sobre enumerações. Parece que você precisa entender alguns conhecimentos básicos sobre o assunto;)
— lealceldeiro

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

Respostas:


307

As enumerações Java não são como as enumerações C ou C ++, que são apenas rótulos para números inteiros.

As enums de Java são implementadas mais como classes - e podem até ter vários atributos.

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

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

A grande diferença é que eles são seguros para o tipo, o que significa que você não precisa se preocupar em atribuir uma enumeração COLOR a uma variável SIZE.

Veja http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html para obter mais informações.


Com base na sua declaração, a melhor prática usando java para criar uma enumeração de números inteiros seqüenciais (semelhante a uma enumeração C ++), para um índice em uma matriz ou algo assim, seria escrever: enum Ids {NAME (0), AGE (1 ), ALTURA (2), PESO (3); } Obrigado, -bn
— bn.

Possivelmente, e especialmente se você serializar os valores integrais em algum lugar.
— lavinio 24/07/11

1
você pode dizer como usar essa enumeração em uma função?
— Bugs Hap

2
É preguiçoso dos padrões Java não permitir que um valor seja definido para uma enumeração. Pelo menos o c # permite que este AND seja do tipo seguro.
— csmith

2
FWIW, C ++ 11 agora tem um tipo seguro enum class.
— Phoenix

92

Sim. Você pode passar os valores numéricos para o construtor da enumeração, da seguinte maneira:

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

  private int value;    

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

  public int getValue() {
    return value;
  }
}

Consulte o Sun Java Language Guide para obter mais informações.


Legal. É possível misturar? Ou seja, atribua apenas números aos valores Enum escolhidos.
— Frederick Nord

modificador privado é redundante para construtores de enumeração
— Nino van Hooff

@FrederickNord - Claro. Basta adicionar um segundo construtor privado sem argumentos que inicialize valueem um (digamos) zero. Em seguida, inclua (digamos) DANCEna lista de valores.
— Stephen C

15

que tal usar desta maneira:

public enum HL_COLORS{
          YELLOW,
          ORANGE;

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

existe apenas um método ..

você pode usar o método estático e passar o Enum como parâmetro como:

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;
            }
          }

Observe que essas duas maneiras usam menos memória e mais unidades de processo. Não digo que essa seja a melhor maneira, mas é apenas outra abordagem.


1
Por que é getColorValue()sincronizado no segundo exemplo?
— josaphatv

@josaphatv Toda a funcionalidade do segundo exemplo é estática, nunca muda. Você pode querer HL_COLORS.getColorValue(HL_COLORS.YELLOW);sem inicializar a enumeração.
— mazunki 9/03

11

Se você usar tipos de enumeração muito grandes, poderá ser útil seguir;

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 você deseja emular a enumeração de C / C ++ (número base e nexos incrementais):

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

A função ordinal () retorna a posição relativa do identificador na enumeração. Você pode usar isso para obter a indexação automática com um deslocamento, como em uma enumeração no estilo C.

Exemplo:

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);
    }
};

Dá a saída:

OPEN:  100
CLOSE: 101
OTHER: 102

Edit: acabei de perceber que isso é muito semelhante à resposta de ggrandes , mas vou deixar aqui porque é muito limpo e o mais próximo possível de uma enumeração de estilo C.


No exemplo, você pega um enum e obtém um int. Você pode mostrar o inverso, pegar um int e terminar com um enum (sem uma caixa de opção explícita para cada valor?)
— ScottF

De acordo com a pergunta, acredito que esta é a resposta mais adequada. Aqui, alteramos o índice padrão de enum para começar de 100 sem definir nova variável e atribuí-las via construtor.
— Rahul Jain

@RahulJain Prefiro usar a resposta aceita. Parece mais limpo para mim.
— lealceldeiro

1

@scottf

Um enum é como um Singleton. A JVM cria a instância.

Se você o criar sozinho com classes, pode ser assim

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 poderia ser usado assim:

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, você provavelmente confundiu por causa do construtor definido no ENUM.

Deixe-me explicar isso.

Quando class loadercarrega a enumclasse, o enumconstrutor também é chamado. Em que!! Sim, é chamado OPENe close. Com que valores 100para OPENe 200paraclose

Posso ter um valor diferente?

Sim,

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; }
}

Mas, é uma prática ruim. enumé usado para representar constantsiguais days of week, colors in rainbowou seja, um pequeno grupo de constantes predefinidas.


0

Eu acho que você está confuso de olhar para enumeradores C ++. Os enumeradores Java são diferentes.

Esse seria o código se você estiver acostumado a enumerações 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);
}
};
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.