I have several switch statements which test an enum
. All enum
values must be handled in the switch
statements by a case
statement. During code refactoring it can happen that the enum
shrinks and grows. When the enum
shrinks the compiler throws an error. But no error is thrown, if the the enum
grows. The matching state gets forgotten and produces a run time error. I would like to move this error from run time to compile time. Theoretically it should be possible to detect the missing enum
cases at compile time. Is there any way to achieve this?
The question exists already "How to detect a new value was added to an enum and is not handled in a switch" but it does not contain an answer only an Eclipse related work around.
We can use also use Enum keyword with Switch statement. We can use Enum in Switch case statement in Java like int primitive.
You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values. Examples would be things like type constants (contract status: “permanent”, “temp”, “apprentice”), or flags (“execute now”, “defer execution”).
Enums don't have methods for iteration, like forEach() or iterator(). Instead, we can use the array of the Enum values returned by the values() method.
You definitely can switch on enums.
In Effective Java, Joshua Bloch recommends creating an abstract method which would be implemented for each constant. For example:
enum Color { RED { public String getName() {return "Red";} }, GREEN { public String getName() {return "Green";} }, BLUE { public String getName() {return "Blue";} }; public abstract String getName(); }
This would function as a safer switch, forcing you to implement the method if you add a new constant.
EDIT: To clear up some confusion, here's the equivalent using a regular switch
:
enum Color { RED, GREEN, BLUE; public String getName() { switch(this) { case RED: return "Red"; case GREEN: return "Green"; case BLUE: return "Blue"; default: return null; } } }
Another solution uses the functional approach. You just need to declare the enum class according with next template:
public enum Direction {
UNKNOWN,
FORWARD,
BACKWARD;
public interface SwitchResult {
public void UNKNOWN();
public void FORWARD();
public void BACKWARD();
}
public void switchValue(SwitchResult result) {
switch (this) {
case UNKNOWN:
result.UNKNOWN();
break;
case FORWARD:
result.FORWARD();
break;
case BACKWARD:
result.BACKWARD();
break;
}
}
}
If you try to use this without one enumeration constant at least, you will get the compilation error:
getDirection().switchValue(new Direction.SwitchResult() {
public void UNKNOWN() { /* */ }
public void FORWARD() { /* */ }
// public void BACKWARD() { /* */ } // <- Compilation error if missing
});
I don't know about the standard Java compiler, but the Eclipse compiler can certainly be configured to warn about this. Go to Window->Preferences->Java->Compiler->Errors/Warnings/Enum type constant not covered on switch.
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