Aug. 2, 2009, 12:08 p.m.
IT

Hard to spot bugs

It took me a full 10 minutes to track down this stupid bug. It is not intuitive. I guess it is the penalty one pays for terseness:

vCostEntry.getCost().put(vDBField, Utils.makeProperString(vExportToExcel).equals("DISCOUNT")?((int)Utils.getDouble(vRawAmount)):GetIntFromFormattedCurrency(vRawAmount));

Some definitions to explain above:

public Map<String, Integer> getCost() {
   return mCost;
}

and

private Integer GetIntFromFormattedCurrency(String pFormattedAmount) {
   ... 
}

So what is the bug? I got a NullPointerException. Assume that Utils.makeProperString never returns null. Assume the Map is not null. Assume in this case the ternary operator evaluated to the else clause.

Here is the solution:

vCostEntry.getCost().put(vDBField, Utils.makeProperString(vExportToExcel).equals("DISCOUNT")?(Integer)((int)Utils.getDouble(vRawAmount)):GetIntFromFormattedCurrency(vRawAmount));

The bug is that the types of the values in the ternary operator ?: need to be consistent with the LHS type, but was not. In this case we tried to:

Integer <= int : Integer

which failed when GetIntFromFormattedCurrency(vRawAmount) returned a null, since Java will try to convert that to the explicit cast performed in the other part of the ternary operator - NOT very intuitive. By casting the first part of the ternary operator back to Integer, all works fine.