Java枚举自动增量条目?

时间:2010-01-13 08:48:03

标签: java enums

Java是否允许类似于好的C甚至C#这样的意思,你可以定义一个枚举,其中的字段会自动增长,并从一个可选的给定值开始?

E.g。

在C或C#中:

enum Foo { A = 10, B, C, D = 5000, E, Fish };

产量A = 10,B = 11,C = 12,D = 5000,E = 5001,鱼= 5002。

2 个答案:

答案 0 :(得分:10)

在Java中,您无法明确指定的序数值。它们总是自动增量,从0开始,无法控制它。

如果您需要其他自定义值,则需要将它们置于构造函数调用中并自行存储。你可以得到自动增量,但它很icky:

import java.util.EnumSet;

// Please don't ever use this code. It's here so you can point and laugh.
enum Foo 
{ 
    A(10), B, C, D(5000), E, Fish;

    private static int nextValue;
    private int value;

    private Foo()
    {
        this(Counter.nextValue);
    }

    private Foo(int value)
    {
        this.value = value;
        Counter.nextValue = value + 1;
    }

    public int getValue() 
    {
        return value;
    }

    private static class Counter
    {
        private static int nextValue = 0;
    }
}

public class Test
{
    public static void main(String[] args)
    {
        for (Foo foo : EnumSet.allOf(Foo.class))
        {
            System.out.println(foo.name() + " " + 
                               foo.ordinal() + " " + 
                               foo.getValue());
        }
    }
}

请注意嵌套类的需要,因为您无法访问枚举构造函数中的静态字段。哎,ick,ick。请不要这样做。

答案 1 :(得分:10)

这是Java Enums的设计选择,不支持更改序数值。基本上,他们不稳定足以依赖他们。如果在示例客户端中更改B和C的位置,则会依赖于序数值。这可能是无意中发生的。

问题在Effective Java Item 31: Use instance field instead of ordinals中进行了描述。

您可以以稳定的方式模拟行为:

enum X{
    A(10), B(A), C(B), D(5000), E(D), F(E);

    private final int value;

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

    X(X preceding){
        this.value = preceding.getValue() + 1;
    }

    public int getValue() {
        return value;
    }

    @Override
    public String toString() {
        return this.name() + "(" + this.value + ")";
    }

    static {
        Set<Integer> values = new HashSet<Integer>();
        for(X x : X.values()) values.add(x.value);
        assert(values.size() == X.values().length); //no duplicates
    }
}

使用此定义,您可以更改值的顺序而不会破坏客户端。

致电for(X x : X.values()) System.out.println(x);返回:

A(10)
B(11)
C(12)
D(5000)
E(5001)
F(5002)