java enum变量是静态的吗?

时间:2013-06-18 10:32:45

标签: java enums

public enum Operations {

    SINGLE,
    MULTIPLE;

    private Type operation;

    public void setOperation(Type operation) {
        this.operation = operation;
    }

    public Type getOperation() {
        return operation;
    }

    public static void main(String[] args) {
        Operations oper1 = Operations.SINGLE;
        oper1.setOperation(Type.GET);

        Operations oper2 = Operations.SINGLE;
        oper2.setOperation(Type.POST);
        System.out.println(oper1.getOperation());
        System.out.println(oper2.getOperation());
    }
}

enum Type {
    POST,
    GET;
}

在上面的代码中,两个操作的操作值都会发生变化。我怎么能有两个具有不同操作类型的Operations.SINGLE实例?

6 个答案:

答案 0 :(得分:15)

是的,实例隐含staticfinal。这意味着代码是不明智的。想象两个线程都调用SINGLE.setOperation(Type);你对你所说的话毫无信心。

来自Java Language Specification, Section 8.9

  

枚举类型(第8.9节)不得声明为抽象;这样做会导致编译时错误。

     

枚举类型是隐式final的,除非它包含至少一个具有类主体的枚举常量。

     

将枚举类型显式声明为final是一个编译时错误。

     

嵌套枚举类型是隐式静态的。允许将嵌套的枚举类型显式声明为静态。

在下一节中:

  

枚举类型的主体可能包含枚举常量。枚举常量定义枚举类型的实例。

     

因为每个枚举常量只有一个实例,所以当比较两个对象引用时,如果知道它们中至少有一个引用枚举常量,则允许使用==运算符代替equals方法。

答案 1 :(得分:11)

  

如何使用不同操作类型的两个Operations.SINGLE实例?

enum背后的基本思想是每个成员都有一个且只有一个实例。这使您可以安全地比较它们的平等性,而不必担心在其他地方创建了另一个SINGLEMULTIPLE

如果您想要SINGLE的多个实例,请将其设为class,而不是enum。您使enum可变的间接指向同一方向的事实:在您的情况下使用enum是错误的选择。

答案 2 :(得分:10)

枚举实例是“静态的”(即表现得像静态变量),但不是immutable

所有线程都看到枚举名称引用的同一个对象 - 它们就像单身一样,来自JVM的铁壳保证只有一个枚举实例。更改枚举的字段会为每个人更改它。

优良作法是在枚举中创建字段final并使其不可变。

答案 3 :(得分:2)

我一年半来不及。但我发现问题没有得到真正解答。

解决方案是使用类而不是枚举,它将这两个枚举作为其字段:

class Operation {
    Quantity quantity;
    Type type;
    Operation(Quantity quantity, Type type) {
        this.quantity = quantity;
        this.type = type;
    }
}

当然,您可以使用枚举而不是类。然后,您必须枚举所有组合:

enum Operation {
    SINGLE_GET(Quantity.SINGLE, Type.GET)
    SINGLE_POST(Quantity.SINGLE, Type.POST)
    MULTIPLE_GET(Quantity.MULTIPLE, Type.GET)
    // ... more options
    // contents same as in class Operation, constructor private by default
}

这两种方法都是有效的,有时你真的想要枚举所有的组合,大多数情况下,你应该坚持使用class方法。

为简洁起见,我没有定义枚举QuantityType,它们只是简单的枚举。

答案 4 :(得分:0)

是的,enum的所有元素都是static final constant。 但正如darijan的另一个答案中所提到的,您的计划存在逻辑错误。

答案 5 :(得分:0)

main方法

的第四行出错
oper1.setOperation(Type.POST);

应该是

oper2.setOperation(Type.POST);