1

I have [a big amount of code that distills down to] this:

class Test {
    enum Bool { False, True };

    static boolean decode(Bool input) {
        boolean b;
        switch (input) {
            case False: b = false; break;
            case True:  b = true;  break;
        }
        return b;
    }
}

javac rejects it on the grounds that:

Main.java:11: error: variable b might not have been initialized
    return b;

I'm a bit confused. I thought the point of enums was to have the values list pinned down at compile-time. In what case might my variable b not have been initialized?

JB.
  • 40,344
  • 12
  • 79
  • 106
  • It is possible for someone to change the `Test$Bool.class` file after compiling and before running the program, and therefore sneak in another enum value. – user253751 Jun 14 '20 at 22:22
  • 3
    The compiler does not consider the branches of switch statements exhaustive unless there is a default clause. Switches on enums are not exempt from this. Just as if you wrote a series of `if/else if` statements, they wouldn't be exhaustive unless you had a final bare `else` clause. – khelwood Jun 14 '20 at 22:24
  • @khelwood: as unsatisfying as it is, I'd accept that if it were an answer. – JB. Jun 21 '20 at 18:49
  • @JB. Fair enough. Answer posted. – khelwood Jun 21 '20 at 18:51
  • Instead of assigning the value in the default branch I'd suggest to throw an `IllegalStateException`. If you ever add another value to your enum you'll be able to find the error faster (if you forgot to edit your switch-Statements) (see: https://stackoverflow.com/questions/33019562/what-is-the-usage-of-default-when-the-switch-is-for-an-enum ) – Felix Jun 21 '20 at 19:16

2 Answers2

2

The compiler does not consider the branches of switch statements exhaustive unless there is a default clause. Switches on enums are not exempt from this. Just as if you wrote a series of if/else if statements, they wouldn't be exhaustive unless you had a final bare else clause, even if the conditions you were checking were logically complementary.

khelwood
  • 55,782
  • 14
  • 81
  • 108
1

That's because it is possible that input is null. Then, the switch case won't initialize it. A fix is to make a default section incase it is null.

static boolean decode(Bool input) {
    boolean b;
    switch (input) {
        case False: b = false; break;
        case True:  b = true;  break;
        default: b = false; // you can make it true too.
    }
    return b;
}

Since I didn't test it, I don't know if it compiles. if not, just initialize b in the beginning.

static boolean decode(Bool input) {
    boolean b = false;
    switch (input) {
        case False: b = false; break;
        case True:  b = true;  break;
    }
    return b;
}
Higigig
  • 1,175
  • 1
  • 13
  • 25
  • 3
    If it's null, I'd expect it to trigger an NPE on switch (or first compare), but *not* to reach the return. – JB. Jun 14 '20 at 22:33