Using Switch-Case Statements and Fall Through Effectively

Switch-Case statements with fall through in Java are often cited as being the source of accidental bugs. Skip a ‘break’ statement and you end up processing the next case after the one you meant to process. Clearly there is a use case for fall through or it wouldn’t be a language feature. While coding something today, I remembered that it is great for processing hierarchical data types where each CASE value is logically a subset of another. I don’t think this is new information, but it was a helpful thing to recall for my own development. In the example below, I am processing dates. What happens to a SECOND should also happen to a MINUTE, what happens to a MINUTE should also happen to an HOUR, etc. I could repeat the code that applies to each case, but the fall through is much more succinct yet still understandable.

     /**
     * For a given date, find the previous value that is an
     * exact value in the value set of timeUnits
     */
    public static Date floor(final Date date, 
                             final TimeUnits timeUnits) {
        final GregorianCalendar calendar 
                = new GregorianCalendar();
        calendar.setTime(date);

        // fall through to each smaller unit
        switch (timeUnits) {
            case MONTH:
                calendar.set(Calendar.DAY_OF_MONTH, 1);
            case DAY:
                calendar.set(Calendar.HOUR_OF_DAY, 0);
            case HOUR:
                calendar.set(Calendar.MINUTE, 0);
            case MINUTE:
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                break;
            default:
                throw new IllegalArgumentException(
                        "Unexpected enum value: " 
                       + timeUnits.name());
        }

        return calendar.getTime();
    }