I think this is due to the specific JLS assignment rules for switch ( JLS 16.2.9 ), which say the following:
"V [un] is assigned after the switch statement if all of the following is true:
- Either there is a default label in the switch block, or V is assigned [un] after the switch expression.
If we then apply this to a conditional V which is the return value of the method, we will see that if there is no branch by default , the value will be conditionally not assigned.
OK ... I extrapolate certain assignment rules to cover the return values, and maybe they don't. But the fact that I could not find something more direct in the specification does not mean that it is not there :-)
There is one more (more justified) reason why the compiler should throw an error. It follows from the binary compatibility rules for enum ( JLS 13.4.26 ), which state the following:
"Adding or reordering constants of type enum will not compromise compatibility with existing binaries."
So how is this applicable in this case? Well, suppose the compiler was allowed to conclude that the OP example switch statement always returned something. What happens if the programmer now changes enum adding an additional constant? According to the JLS binary compatibility rules, we did not violate binary compatibility. However, a method containing a switch can now (depending on its argument) return an undefined value. This cannot be allowed, so switching should be a compilation error.
In Java 12, switch enhancements have been introduced, including switch expressions. This faces the same problem with enumerations that vary between compile time and runtime. According to JEP 354 , they solve this problem as follows:
The cases of the switch statement must be exhaustive; for all possible values there must be an appropriate switch label. (Obviously, switch statements do not have to be exhaustive.)
In practice, this usually means that a default condition is required; however, in the case of an enumeration switch expression that encompasses all known constants, the compiler inserts a default clause to indicate that the enumeration definition has changed between compile time and runtime. Using the default implicit insertion of a sentence makes the code more reliable; now that the code has been recompiled, the compiler checks that all cases are handled explicitly. If the developer inserted an explicit default sentence (as today), the possible error would be hidden.
The only thing that is not entirely clear is what the implicit default offer actually does. I assume this will result in an unchecked exception. (Currently, JLS for Java 12 has not been updated to describe new switch expressions.)