Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to enforce that you're switching over all defined values of an enum in Java? [duplicate]

Suppose you have an enum with 3 values:

enum Colors { RED, GREEN, BLUE }

You switch over all values of it in some method, thinking you've handled all cases:

switch (colors) {
    case RED: ...
    case GREEN: ...
    case BLUE: ...
}

Then later, you add a new value to the enum:

enum Colors { RED, GREEN, BLUE, YELLOW }

And everything still compiles fine, except you're silently missing a case for YELLOW in the method. Is there a way to raise a compile-time error in such a scenario?


edit: Do not understand why this was marked a dupe of Can I add and remove elements of enumeration at runtime in Java. Since the answer there was "no", that means it should be possible to know at compile-time all values of an enum, and therefore what I'm asking for should be possible for the compiler/some code analysis tool to implement, right?

like image 637
James Ko Avatar asked Sep 10 '17 18:09

James Ko


3 Answers

No. But enums are classes. So you can use polymorphism:

enum Color { 
    RED {
        @Override
        public void foo() { ... }
    },
    GREEN {
        @Override
        public void foo() { ... }
    },
    BLUE {
        @Override
        public void foo() { ... }
    };

    public abstract void foo();
}

Now, if you add a color, the compiler won't let you add it it it doesn't override the abstract method.

And instead of

switch (color) {
    case RED: ...
    case GREEN: ...
    case BLUE: ...
}

you can just use

color.foo();

Note that Kotlin allows to do what you want, if Kotlin is an option.

Also note that BLUE is a color, not a colors. So the enum should be named Color, not Colors.

like image 178
JB Nizet Avatar answered Oct 03 '22 21:10

JB Nizet


That depends on the compiler. The Eclipse IDE built-in compiler can be configured to raise an error in that case.

Windows/Preferences Java Compiler Errors/Warnings "Incomplete 'switch' cases on enum" can be set to "Error".

EDIT:

There even is a sub-option "signal even if 'default' case exists".

like image 27
Ralf Kleberhoff Avatar answered Oct 03 '22 19:10

Ralf Kleberhoff


I don't think there is a default way of doing this. It might be possible with some external tools.

Why not providing a default in the switch statement and raising an Exception. Besides, you should have enough unit tests to test this scenario, if you compile your project and all you unit tests are ok, this would mean you aren't testing deep enough.

like image 41
Joey Reinders Avatar answered Oct 03 '22 21:10

Joey Reinders