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

In the above code, the value of operation changes for both the Operations. How can I have two instances of Operations.SINGLE with different operation type?

Optional
  • 4,387
  • 4
  • 27
  • 45
  • 1
    Your question would be easier to understand if you told us what was printed to stdout. (I assume it prints `POST` twice?) โ€“ Duncan Jones Jun 18 '13 at 10:34
  • SINGLE is equivalent to public static final Operations SINGLE = new Operations("SINGLE", 0) โ€“ Blackbelt Jun 18 '13 at 10:39

6 Answers6

16

Yes, instances are implicitly static and final. This means that the code is unwise. Imagine two threads both calling SINGLE.setOperation(Type); you will have no confidence in what you are calling.

From the Java Language Specification, Section 8.9:

Enum types (ยง8.9) must not be declared abstract; doing so will result in a compile-time error.

An enum type is implicitly final unless it contains at least one enum constant that has a class body.

It is a compile-time error to explicitly declare an enum type to be final.

Nested enum types are implicitly static. It is permissible to explicitly declare a nested enum type to be static.

And in the next section:

The body of an enum type may contain enum constants. An enum constant defines an instance of the enum type.

Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.

Community
  • 1
  • 1
Eric Jablow
  • 7,874
  • 2
  • 22
  • 29
11

How can I have two instances of Operations.SINGLE with different operation type?

The fundamental idea behind an enum is that there is one, and only one, instance of each of its members. This is what lets you safely compare them for equality, without fear that there's another SINGLE or MULTIPLE created in some other place.

If you want multiple instances of SINGLE, make it a class, not an enum. The fact that you made your enum mutable indirectly points in the same direction: using enum is a wrong choice in your situation.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
10

Enum instances are "static" (ie behave like static variables), but are not immutable.

All threads see the same object referred to by the enum name - they are like singletons, with an iron-clad guarantee from the JVM that there is only ever one instance of an enum. Changing a field of an enum changes it for everyone.

It is good practice to make your fields final in an enum and to make them immutable.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
2

I'm one year and a half too late. But I see the question was not really answered.

The solution would be using a class instead of enum, that has those two enums as its fields:

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

You can, of course, use enum instead of class. Then you'll have to enumerate all combinations:

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
}

Both approaches are valid, sometimes you really want to enumerate all the combinations, most of the time, however, you should probably stick with the class approach.

For brevity, I didn't define the enums Quantity and Type, they are just simple enums.

Vlasec
  • 5,500
  • 3
  • 27
  • 30
0

Yes, all elements of enum are static final constant. However as mentioned in another answer by darijan, there is a logical mistake in your program.

Mubin
  • 4,192
  • 3
  • 26
  • 45
0

There is an error in fourth line of main method

oper1.setOperation(Type.POST);

should be

oper2.setOperation(Type.POST);
darijan
  • 9,725
  • 25
  • 38