The specification of 'switch' behavior at runtime does not properly handle Strings and enums.
"Otherwise, if the result is of a reference type, it is subject to unboxing conversion (��5.1.8)."
There is no unboxing conversion that can be applied to Strings or enums.
In the case of a boxed number, it may make more sense to box the case constants than to unbox the value, since the compile-time check was that the case constant was assignment-compatible with the wrapper class. (This is just a matter of presentation -- there's no observable difference, since we've already checked for null.)
"If one of the case constants is equal to the value of the expression,then we say that the case label matches."
Primitives have a well-defined notion of equality (except perhaps floating-points, which aren't applicable here). Reference types do not: this may be reasonably interpreted as either "val == const" or "val.equals(const)". We should be explicit.
(Aside: for primitives, a subtle problem here is that we don't explicitly assert that a conversion takes place. (E.g., the integer constant '1' is assignment-compatible with type byte, but the spec doesn't explicitly say that, at runtime, '1' is narrowed to a byte.) I'm not sure we're consistent about this everywhere, though -- compare 14.17 and 15.26.1 -- so it's a minor problem.)