Eclipse forces me to use a default
case for any switch
including those listing all declared enum
values, allegedly because of the language specification [1]. This is unfortunate because Android Studio, in which the project is developed in parallel, does not, and would naturally warn me about all switch
es which become incomplete if ever the enum
is changed. While I would prefer the latter behaviour because the former makes enum
changes actually more error-prone (see example below), I am in no position to choose, so I need to find how to do this right for both. I suppose if there is a place in a code which should under any circumstances remain unreachable but still removing the line is not an option, throwing an Error
seems like the natural thing to do there. But which one, is there a generally accepted subclass for such a scenario (perhaps extending to other "forced" unreachable places)? Or is it acceptable to simply throw a quick-and-dirty new Error("enum name")
just for the sake of it, instead of writing my own just to be never used?
In the example:
public static enum Color {
RED,
GREEN,
BLUE;
@Override
public String toString() {
switch(this) {
case RED:
return "Red";
case GREEN:
return "Green";
case BLUE:
return "Blue";
default:
/* never reached */
throw new ThisCanNeverHappenError();
}
}
}
adding WHITE
to the enum
makes this switch
and possibly many more throughout the code silent sources of nasty errors as flow control finds them to be just fine.
You should not throw an Error
. A better exception should be IllegalStateException
:
switch(this) {
case RED:
return "Red";
case GREEN:
return "Green";
case BLUE:
return "Blue";
default:
throw new IllegalStateException("Unexpected enum value: " + this.name());
}
On a different note, you shouldn't use a switch
statement there anyway. Add a field to the enum. Also note that enums are always static
, so you can remove that keyword.
public enum Color {
RED ("Red"),
GREEN("Green"),
BLUE ("Blue");
private final String displayText;
private Color(String displayText) {
this.displayText = displayText;
}
public String getDisplayText() {
return this.displayText;
}
@Override
public String toString() {
return this.displayText;
}
}