Take a look at the following code, and try to guess what is printed:

public static void main(String[] args) {
                Date today = new Date();
               
                Calendar c = new GregorianCalendar();
                c.add(Calendar.DAY_OF_YEAR, 10);
               
                System.out.println(c.after(today));
        }

What is printed?

1. true
2. false
3. It doesn’t compile
4. Runtime error

From a logical perspective, #1 is right - 10 days from now is after now, so you’d expect to see ‘true’ printed. From a language perspective, you may think “you are passing in a java.util.Date to a function on java.util.Calendar, so it wouldn’t compile”, and choose #3. Neither of these are correct - the block of code above completes normally and prints ‘false’, which is not what we wanted.

If you take a look at the javadocs for java.util.Calendar, it is easy to see why. The signature for after (and before) is public boolean after(Object when), but if you pass anything but a java.util.Calendar in, it will *always* return false. This is an unfortunate api design problem - it is reasonable to expect that you could pass in a java.util.Date, or even a long representing a timestamp to compare to the Calendar instance and it would work normally. The fact that either of those options compiles and runs without error can cover up the flaw in your code, and be difficult to track down (which is how I came across it and decided to write this post).

I am stumped trying to come up for a good reason for the method to accept Object (which means anything can be passed in - even primitives from Java 5 on) only to return false if it is anything other than java.util.Calendar. The method signature should be public boolean after(java.util.Calendar when), so that you get a compile error instead of a silent failure at runtime.

Now, this library has been around since JDK 1.1, so I’m not exposing a new design flaw or anything. I am, however, curious as to how something so clearly anti-idiomatic Java (and anti-static typing) made it into a core Java library. Anyone have any ideas? The Date/Time APIs in Java are generally pretty bad anyway, but this seems especially poorly done.

I mostly write business code, and not much in the way of API code, but I have been reading the 2nd edition of Josh Bloch’s Effective Java and it has given me a better appreciation for the thought and effort that goes into creating useful APIs. It is always interesting to see some of the really good *and* really bad examples of API design in the core Java libraries.