# Order matters
I ran into an odd problem tonight. I have a simple Money class which wraps a BigDecimal and provides a safe subset of BigDecimal's methods while enforcing a sensible scale.
Any guess what could be wrong with the following code snippet?
public class Money {
public static final Money ZERO = new Money(0);
private static final MathContext MC = MathContext.UNLIMITED;
private final BigDecimal amt;
public Money(double amt) {
this.amt = new BigDecimal(amt, MC);
}
...
If it's obvious to you, give yourself a Noddy Badge. The BigDecimal constructor gets given the parameter and the MC constant, but throws a NullPointerException, because MC is null. Why? Because ZERO is constructed before MC. It would be nice to think that all static code is executed before anything else, but it makes sense that you couldn't have that, in this case.
It would also be nice to think that the Java compiler would reorder static code to make it work, but that isn't too practical either. Static code is executed sequentially, and so ZERO is constructed before MC.
I like keeping variables ordered public-first, then private, but in this case I'd have to swap the two statements around. An alternative is to use a static block, a la:
public class Money {
public static final Money ZERO;
private static final MathContext MC;
static {
MC = MathContext.UNLIMITED;
ZERO = new Money(0);
}
private final BigDecimal amt;
public Money(BigDecimal amt) {
this.amt = new BigDecimal(amt.doubleValue(), MC);
}
...
This is probably better regardless, since it makes the order of instantiation more explicit. What's more, you could put the static block before the declarations, and it'll still work.
There are people who've read the Java language spec and could quote chapter and verse and wouldn't make mistakes like this. I'm not one of them :-)
(Update: as an added bonus, the first version of this post wasn't using MathContext properly, which I've only just discovered. That's probably worth a post in its own right. Silly BigDecimals.)
File under: java : {2007.11.26 - 21:26} : Comments (0)