Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java枚举自动递增项?_Java_Enums - Fatal编程技术网

Java枚举自动递增项?

Java枚举自动递增项?,java,enums,Java,Enums,Java是否允许像好的ol'C甚至C#这样的东西,从某种意义上说,您可以使用自动增加值的字段定义枚举,并从可选的给定值开始 例如 在C或C中: 生成A=10、B=11、C=12、D=5000、E=5001、Fish=5002。在Java中,您根本无法显式指定序号值。它们总是从0开始自动递增,没有控制权 如果需要其他自定义值,则需要将它们放入构造函数调用中并自己存储。您可以获得自动增量,但它也很讨厌: import java.util.EnumSet; // Please don't ever

Java是否允许像好的ol'C甚至C#这样的东西,从某种意义上说,您可以使用自动增加值的字段定义枚举,并从可选的给定值开始

例如

在C或C中:


生成A=10、B=11、C=12、D=5000、E=5001、Fish=5002。

在Java中,您根本无法显式指定序号值。它们总是从0开始自动递增,没有控制权

如果需要其他自定义值,则需要将它们放入构造函数调用中并自己存储。您可以获得自动增量,但它也很讨厌:

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

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

这是Java枚举的设计选择,不支持更改序号值。基本上,它们不稳定,不足以依赖它们。如果在示例中更改B和C的位置,则客户机将根据序数值而断开。这可能是无意中发生的

这个问题用有效的Java描述

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

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

不过有点差劲——它们有它们的用处。例如,当我不希望枚举的值低于N时(可能我想将该范围保留为禁区)。但我也不想自己手动定义每个整数值…@alex:这意味着您应该有一个字段,根据您想要的范围限制,从序号计算数字。@alex-模拟版本应该适合您。它是稳定的,并且不必显式地将每个int值放入其中。我喜欢使用前面的值。很好。嘿,我想我会求助于最终的静态int,然后手动完成。指定
B(A),C(B),…,
并没有为我节省太多:)。不过,谢谢。默认构造函数需要更新Counter.nextValue,您也可以直接在Foo中删除nextValue。@Yuliy:无参数构造函数调用参数化的构造函数,所以这就是更新Counter.nextValue。将nextValue直接放在Foo中是行不通的——至少在我使用的javac版本中是行不通的。它阻止你访问构造函数中的静态字段。非常好的把戏,Jon,我知道你不会同意,但我会用它:p,谢谢!
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
    }
}
A(10)
B(11)
C(12)
D(5000)
E(5001)
F(5002)