Search code examples
javacoding-styleenums

Enum method overriding


I've found Enums defined like the following:

public Enum MyEnum {

   ONE
   {
      @Override
      public int getSomething() {
         return 1;
      } 
   },

   TWO
   {
      @Override
      public int getSomething() {
        return 2;
      }
   }

   int getSomething()
   {
      return 0;
   }
}

Somehow I feel some type of discomfort with this implementation because I would think that ideally a field should be defined for this purpose and the class should look something like:

public Enum MyEnum{

   ONE(1),
   TWO(2)

   private int theSomething;

   private MyEnum(int something) {
      theSomething = something;
   }

   int getSomething()
   {
      return theSomething;
   }
}

The problem is that apart from personal discomfort I cannot find any good reason to change this code. Do any exists?


Solution

  • (moved from comment)

    Your first example is used commonly to implement a finite state machine in Java. It eliminates the need for every method having to have a if (state == FOO) {} else if (state == BAR) etc

    class MyFSM {
    
        enum State {
            FIRST_STATE {
                @Override
                void start(MyFSM fsm) {
                    fsm.doStart();
                }
                @Override
                void stop(MyFSM fsm) {
                    throw new IllegalStateException("Not Started!");
                }
            },
            SECOND_STATE {
                @Override
                void start(MyFSM fsm) {
                    throw new IllegalStateException("Already Started!");
                }
                @Override
                void stop(MyFSM fsm) {
                    fsm.doStop();
                }
            };
    
            abstract void start(MyFSM fsm);
            abstract void stop(MyFSM fsm);       
        }
    
        private volatile State state = State.FIRST_STATE;
    
        public synchronized void start() {
            state.start(this);
        }
    
        private void doStart() {
            state = SECOND_STATE;
        }
    
        public synchronized void stop() {
            state.stop(this);
        }
    
        private void doStop() {
            state = FIRST_STATE;
        }
    }