Atom Feed SITE FEED   ADD TO GOOGLE READER

Java language tweak: protected switch

I have an enumerated type, and it's possible that I'll be adding more values in the future.
public enum Office {
CALGARY, REGINA, TORONTO, BERLIN;
}


Somewhere in the code, I switch on this type:
public CurrencyCode getCurrencyForPayingEmployees(Office office) {
switch(office) {
case CALGARY:
case REGINA:
case TORONTO:
return CurrencyCode.CAD;
case BERLIN:
return CurrencyCode.EUR;
}
}


Unfortunately, this doesn't compile. Javac will tell me that the method doesn't always return, because it doesn't know that I've covered all applicable cases. I appease the compiler by adding this line at the end of the method:
    default:
throw new AssertionError();


Now whenever I add a new office I have to scour through the code to find the switch statements and add the appropriate behaviour. I get no compiler help from this, so if I miss one, I'll end up getting AssertionErrors in test or production.

The classical solution for this is the visitor pattern, but it's somewhat verbose and doesn't work very well if when I don't control the enum that I'm switching on.

What if Java had a 'protected' switch statement that protected me from forgetting an element? The syntax would be similar:
public CurrencyCode getCurrencyForPayingEmployees(Office office) {
protected switch(office) {
case CALGARY:
case REGINA:
case TORONTO:
return CurrencyCode.CAD;
case BERLIN:
return CurrencyCode.EUR;
}
}


But there are a few differences:
  • the compiler enforces that every type is covered, and shows a compiler warning if a particular enum element is not present.
  • if we return from all cases, we don't need an extra 'return' statement at the bottom to handle the nonexistent other case.

    If ever I have the time, I'll see if I can hack javac and contribute this to KSL.
  • Eclipse can do this (enabling warnings when not all cases are covered in switch/case statement) in Window/Preferences/Java/Compiler/Warnings or similar. Enabled after a full recompile, so maybe it's a compiler feature?
    Good for Eclipse, that's pretty cool.

    But I imagine there's no way to tell Eclipse whether a particular switch is intended to cover all cases - that's what the protected keyword would do. As well, without language support I still need to provide a redundant return or throw.
    I suggested something similar a while back - http://jroller.com/page/scolebourne?entry=java_language_enum_switch. It is apparently also being considered by the extended annotations JSR.
    Sweet - the annotation is a nice approach because it doesn't require a language change, and could be implemented on Java 5 and 6.

    But it does mean that you'll still need the redundant return or throw at the end of the method.
    You should have a look at AOP, AspectJ, and AJDT for eclipse users may helps...