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?

qrtt1
fonte
@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.

lavinio
fonte
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.

Paul Morie
fonte
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.

Maher Abuthraa
fonte
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;
    }
}
serdar
fonte
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
ggrandes
fonte
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.

maharvey67
fonte
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");
    }
}
sperling
fonte
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.

Gibbs
fonte
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);
}
};
Coristat
fonte