Interestingly, all answers so far are basically saying “because the specification says so”, which is correct but not really satisfying. Before Java 7, String
s were not allowed and that was often treated like being carved in stone.
But technical obstacles shouldn’t drive language design. If there is no way to compile it to efficient code, it might still get compiled to the equivalent of if … else …
clauses, and still have a win on source code brevity. In the case of String
values, there is an efficient way. Just switch over the invariant hashcode and perform an equals
check on the match candidate. In fact, the specification does not mandate to use the hash code, it could be any invariant int
property, e.g. the length or the first character, but it’s value should be different for each String
.
Similarly, a switch
over Class
objects is possible. It’s hash code is not guaranteed to be the same, but each class has a constant name with a constant hash code. E.g. the following works:
public class ClassSwitch {
static final class Foo {}
static final class Bar {}
static final class Baz {}
public static void main(String... arg) {
Class<?> cl=Bar.class;
switch(cl.getSimpleName().hashCode()) {
case 70822:
if(cl==Foo.class) {
System.out.println("case Foo:");
}
break;
case 66547:
if(cl==Bar.class) {
System.out.println("case Baz:");
}
break;
case 66555:
if(cl==Baz.class) {
System.out.println("case Baz:");
}
break;
}
}
}
I used the simple name instead of the qualified name, so that this example code is package independent. But I think, the picture is clear. It is possible to implement efficient switch
statements for any kind of object which has a constant int
property that can be predicted at compile time. That said, there is also no reason not to support long
switches. There are plenty of ways to calculate a suitable int
from a long
…
So there are another important decisions to make.
Is this feature really a benefit? It looks like code smell—even the addition of String
support was controversial. It does not add new possibilities as you may do the same with if
-else
for a small number of classes or a HashMap<Class,SomeHandlerType>
for bigger numbers. And it doesn’t really look like something that is needed so often, that it is worth expanding the language specification, even if it is just a single sentence that has to be added.
These are the considerations that drive the language design, but it’s not that minds and balances cannot change. So I’m not saying that’s impossible that a future version gets this feature.
But well, looking at the quality of generated String
switch
code I’d rather code my switches
manually…
c.getName()
and in case, use class name instead – Quilloninstanceof
and casting.If you want a real pattern-matching, take a look at Scala's – Falterinstanceof
, or could be easily implemented with them – Falter