我可以在Java中设置枚举起始值吗?


194

我使用枚举来使一些常量:

enum ids {OPEN, CLOSE};

OPEN值为零,但我希望它为100。可能吗?


@ScottF您要如何使用枚举?
阿尼什·B

在最上面的答案中,有一个枚举定义。我想要一个示例,说明如何在代码中使用该定义的枚举。例如,如何将定义的ctor用于创建具有特定整数值的枚举实例。
ScottF

@ScottF(如果我是您),而不是在这个帖子上设置赏金,我宁愿发布一个全新的问题.....,或者阅读有关枚举的文档。似乎您需要掌握一些核心知识;)
lealceldeiro

enum ids {OPEN = 100, CLOSE};
奥斯卡先生

Answers:


307

Java枚举不同于C或C ++枚举,它们实际上只是整数的标签。

Java枚举的实现更像类-甚至可以具有多个属性。

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

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

最大的区别是它们是类型安全的,这意味着您不必担心将COLOR枚举分配给SIZE变量。

有关更多信息,请参见http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html


根据您的陈述,使用java创建一个连续整数的枚举(类似于C ++枚举)的最佳实践,是针对数组或其他内容的索引编写:枚举Ids {NAME(0),AGE(1 ),HEIGHT(2),WEIGHT(3); } -bn
bn。

可能,尤其是如果您曾经在某个地方序列化整数值。
lavinio

1
你能告诉我如何在函数中使用这个枚举吗?
错误发生

2
Java标准不允许为枚举设置值是懒惰的。至少c#允许此AND类型安全。
csmith

2
FWIW,C ++ 11现在具有类型安全的enum class
凤凰城

92

是。您可以将数值传递给枚举的构造函数,如下所示:

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

  private int value;    

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

  public int getValue() {
    return value;
  }
}

有关更多信息,请参见《Sun Java语言指南》


凉。可以混合吗?即,仅将数字分配给所选的Enum值。
Frederick Nord

私有修饰符对于枚举构造函数是多余的
Nino van Hooff

@FrederickNord-好的。只需添加第二个不带参数的私有构造函数,value即可将其初始化为零。然后DANCE在值列表中包括(说)。
斯蒂芬C

15

如何使用这种方式:

public enum HL_COLORS{
          YELLOW,
          ORANGE;

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

只有一种方法..

您可以使用静态方法并将Enum作为参数传递,例如:

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

请注意,这两种方式使用的内存更少,进程单位更多。.我并不是说这是最好的方式,而是另一种方式。


1
为什么getColorValue()在第二个示例中进行同步?
josaphatv

@josaphatv第二个示例中的所有功能都是静态的,它永远不会改变。您可能希望HL_COLORS.getColorValue(HL_COLORS.YELLOW);不初始化枚举。
马祖基

11

如果使用非常大的枚举类型,则可以使用以下内容;

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

如果要模拟C / C ++枚举(基数和下一个增量):

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

ordinal()函数返回标识符在枚举中的相对位置。您可以使用它来获取带有偏移量的自动索引,就像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);
    }
};

给出输出:

OPEN:  100
CLOSE: 101
OTHER: 102

编辑:刚刚意识到这与ggrandes的答案非常相似,但我将其保留在这里,因为它非常干净,并且与C风格枚举几乎一样。


在该示例中,您将得到一个枚举并得到一个int。您能显示相反的意思吗,取一个int并以一个枚举结尾(每个值都没有明确的切换格?)
ScottF

根据问题,我认为这是最合适的答案。在这里,我们将枚举的默认索引更改为从100开始,而没有定义新变量并通过构造函数分配它们。
拉胡尔·in那

@RahulJain我宁愿使用接受的答案。对我来说似乎更干净。
lealceldeiro

1

@斯科特

一个枚举就像一个单例。JVM创建实例。

如果您将自己通过类创建它,则可能看起来像这样

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 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,您可能会因为ENUM中定义的构造函数而感到困惑。

让我解释一下。

class loader加载enum类时,enum构造函数也被调用。什么!!是的,它被称为OPENclose。用什么值100OPEN200close

我可以有不同的价值吗?

是,

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

但是,这是不好的做法。enum用于表示constantslike days of weekcolors in rainbow即这样的一小组预定义常数。


0

我认为您对查看C ++枚举器感到困惑。Java枚举器是不同的。

如果您习惯使用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);
}
};
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.