Java Enums and Switch Statements - the default case?

enums, java

Solution

You could always use the Enum with Visitor pattern:

enum Mode {
  on {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitOn();
      }
  },
  off {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitOff();
      }
  },
  standby {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitStandby();
      }
  }

  public abstract <E> E accept( ModeVisitor<E> visitor );

  public interface ModeVisitor<E> {
      E visitOn();
      E visitOff();
      E visitStandby();
  }
}

Then you would implement something like the following:

public final class ModeColorVisitor implements ModeVisitor<Color> {
    public Color visitOn() {
       return getOnColor();
    }

    public Color visitOff() {
       return getOffColor();
    }

    public Color visitStandby() {
       return getStandbyColor();
    }

}

You'd use it as follows:

return model.getMode().accept( new ModeColorVisitor() );

This is a lot more verbose but you'd immediately get a compile error if a new enum was declared.

Problem

For people suggesting throwing an exception: Throwing an exception doesn't give me a compile-time error, it gives me a runtime error. I know I can throw an exception, I'd rather die during compilation than during runtime. First-off, I am using eclipse 3.4. I have a data model that has a mode property that is an Enum. ``` enum Mode {on(...), off(...), standby(...); ...} ``` I am currently writing a view of this model and I have the code ``` ... switch(model.getMode()) { case on: return getOnColor(); case off: return getOffColor(); case standby: return getStandbyColor(); } ... ``` I am getting an error "This method must return a result of type java.awt.Color" because I have no default case and no return xxx at the end of the function. I want a compilation error in the case where someone adds another type to the enum (e.g. shuttingdown) so I don't want to put a default case that throws an AssertionError, as this will compile with a modified Mode and not be seen as an error until runtime. My question is this: Why does EclipseBuilder (and javac) not recognize that this switch covers all possibilities (or does it cover them?) and stop warning me about needing a return type. Is there a way I can do what I want without adding methods to Mode? Failing that, is there an option to warn/error on switch statements that don't cover all of the Enum's possible values? Edit: Rob: It is a compile error. I just tried compiling it with javac and I get a "missing return statement" error targeting the last } of the method. Eclispe just places the error at the top of the method.

Original source