Suppose I have an enum Color
with 2 possible values: RED
and BLUE
:
public enum Color {
RED,
BLUE
}
Now suppose I have a switch statement for this enum where I have code for both possible values:
Color color = getColor(); // a method which returns a value of enum "Color"
switch (color) {
case RED:
...
break;
case BLUE:
...
break;
default:
break;
}
Since I have code block for both possible values of the enum, what is the usage of default
in the above code?
Should I throw an exception if the code somehow reaches the default
block like this?
Color color = getColor(); // a method which returns a value of enum "Color"
switch (color) {
case RED:
...
break;
case BLUE:
...
break;
default:
throw new IllegalArgumentException("This should not have happened");
}
The default value for an enum is zero. If an enum does not define an item with a value of zero, its default value will be zero.
We can use also use Enum keyword with Switch statement. We can use Enum in Switch case statement in Java like int primitive.
The default statement is optional and can appear anywhere inside the switch block. In case, if it is not at the end, then a break statement must be kept after the default statement to omit the execution of the next case statement.
It is good practice to throw an Exception as you have shown in the second example. You improve the maintainability of your code by failing fast.
In this case it would mean if you later (perhaps years later) add an enum value and it reaches the switch statement you will immediately discover the error.
If the default value were not set, the code would perhaps run through even with the new enum value and could possibly have undesired behavior.
The other answers are correct in saying that you should implement a default
branch that throws an exception, in case a new value gets added to your enum in the future. However, I would go one step further and question why you're even using a switch
statement in the first place.
Unlike languages like C++ and C#, Java represents Enum values as actual objects, which means that you can leverage object-oriented programming. Let's say that the purpose of your method is to provide an RGB value for each color:
switch (color)
case RED:
return "#ff0000";
...
Well, arguably, if you want each color to have an RGB value, you should include that as part of its description:
public enum Color
{
RED("#FF0000"),
BLUE("#0000FF");
String rgb;
public Color(String rgb) {
this.rgb = rgb;
}
public getRgb() { return this.rgb; }
}
That way, if you add a new color later, you're pretty much forced to provide an RGB value. It's even more fail-fast than the other approach, because you'll fail at compile-time rather than run-time.
Note that you can do even more complicated things if you need to, including having each color provide its own custom implementation of an abstract method. Enums in Java are really powerful and object-oriented, and in most cases I've found I can avoid needing to switch
on them in the first place.
Compile time completeness of the switch cases doesn't guarantee runtime completenes.
Class with a switch statement compiled against an older version of enum may be executed with a newer enum version (with more values). That's a common case with library dependencies.
For reasons like these, the compiler considers the switch
without default
case incomplete.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With