3

Consider the following code:

enum MyEnum {
  A, B, C;
}

int foo(MyEnum e) {
  switch (e) {
    case A:
      return 1;
    case B:
      return 2;
    case C:
      return 3;
  }
}
^ error: missing return statement

The compiler does not like this. Contrast this example with:

int bar() {
  if (...) {
    return 1;
  } else {
    return 2;
  }
}

The issue with the switch could be addressed with a default case, but you could argue that's unneeded here. All of the enum values are covered in the cases of the switch. Does static analysis of the switch statement know that, with returns in an exhaustive switch, the code block after the switch statement is unreachable?

I tried looking at the language spec, but I didn't see this point clearly addressed.

Zhe
  • 396
  • 1
  • 13
  • 1
    And then one developer decides to add a `D` to `MyEnum`, which causes 20 unrelated classes to no longer compile, because they all had switches without default case. – Jaroslaw Pawlak May 30 '18 at 14:58
  • @JaroslawPawlak That's not a problem because of tests. – Zhe May 30 '18 at 15:30
  • 1
    @vincrichaud Yes, looks like this is a dupe. Thanks for the pointer. – Zhe May 30 '18 at 15:35
  • 2
    @JaroslawPawlak Oh, I prefer that to that 20 unrelated class to be turned out to be buggy, – Xwtek Dec 13 '18 at 00:56
  • @JaroslawPawlak that's the entire point of using an enum. The API changed, so all users of the enum should check how the change affects them. – tjalling Feb 19 '23 at 13:27

1 Answers1

0

Well, Java does not implement enums natively as other languages like C/C++ or .NET. They are just instances of a (final) class. So in fact your operator == compares for reference equality rather than integer values as you might have suggested.

This is the reason, why the switch statement is not complete. The reference might just be null.

Furthermore you might have defined your own enum class with a public constructor which might create any arbitrary number of instances.


By the way: the by far easiest way to implement your foo method is

int foo(MyEnum e)
{ return e.ordinal() + 1;
}

But note that .ordinal() does not return any value associated with your enum constant. It is just the index in order of definition.

Marcel
  • 1,688
  • 1
  • 14
  • 25
  • The spec specifically says that the switch will throw an NPE on input, though that's not a checked exception: "When the switch statement is executed, first the Expression is evaluated. If the Expression evaluates to null, a NullPointerException is thrown and the entire switch statement completes abruptly for that reason." – Zhe May 30 '18 at 15:32
  • And sorry I was not clear, but I'm not trying to implement this exact example. This is just a trivial case to illustrate what I'm talking about. Suppose you're always returning the result of other method calls. – Zhe May 30 '18 at 15:35