The runtime behavior of 'switch' for Strings and enums is poorly specified.
After checking for 'null', we have this rule:
"Otherwise, if the result is of a reference type, it is subject to unboxing conversion"
That doesn't apply where the reference type is String or an enum. (Unboxing conversion is undefined in these cases.)
(Aside: later references to "the value of the expression" are a little unclear that what they mean is the value after unboxing.)
Subsequently, a case label in a switch statement is said to "match" according to the following definition:
"If one of the case constants is equal to the value of the expression, then we say that the case label _matches_."
It is not clear whether, for a reference, this means identity ('==') or 'equals'. In practice, for Strings, the latter is what is wanted. The distinction is moot for enums, since the two kinds of equality are equivalent.
(Aside: as a design note, may be helpful to observe in the text that Strings and enums have fixed 'equals' behavior with no side-effects -- the String class and 'Enum.equals' method are 'final' -- which allows implementations to optimize the search for a match without impacting observable behavior.)