Tuesday, 31 March 2009

Less than Intuitive

I'm struggling with a cold and not feeling very sharp at the moment. Perhaps this accounts for me being over-sensitive about a couple of classes in Java that I've tripped over today? Or maybe writing JUnit tests most of the afternoon has numbed my mind?

The first is java.util.Calendar. It's not something I use every day and this little snippet is typical of mistakes I've made before.

    Calendar calendar = Calendar.getInstance();
    calendar.set(2009, 03, 23);

I wanted March but my output was, of course, Thu Apr 23 00:00:00 BST 2009. Quite reasonably, if not intuitively, months are zero based in java.util.Calendar. But it's an easy one to slip on if you aren't paying attention or are feeling too lazy to type Calendar.MARCH as the second argument.

The second thing I fell foul of was the infamously tricky java.math.BigDecimal. Exemplified by this (although my actual problem was not so obvious):

    BigDecimal a = new BigDecimal("123");
    BigDecimal b = new BigDecimal("123.0");
    System.out.println(a.equals(b) ? "Same" : "Different");

The output in this case is Different. Again perfectly reasonable when you consider what BigDecimal sets out to achieve in terms of rounding control, but still less than intuitive for a spluttering and sneezing developer who's not used it for a while. Mental note: remember to specify the scale of numbers:

    BigDecimal a = new BigDecimal("123").setScale(2);
    BigDecimal b = new BigDecimal("123.0").setScale(2);

And all is well. Maybe after a good night's sleep I'll be the same.


Chris B said...

At least you didn't succumb to a pitfall I've seen:

BigDecimal a = new BigDecimal("123");

which forgets that BigDecimal is immutable, and the setScale method actually returns a new object with the required scale :-(

san-ho-zay said...

Indeed. Even obvious mistakes with immutable objects like:

BigDecimal a = new BigDecimal("123);

are an easy trap to fall into if you get into a mutable object mindset.