Monday, January 19, 2009

Getting your numbers straight when programming in Java

While going through a cursory code inspection, some common patterns emerged above the throng. A few of them tend to trick even the more experienced programmers, less on the account of their skill than on the account of being syntactically too small to spot:

Automatic type promotion

Programmers tend to rely on the compiler to automatically promote smaller types into larger types, which works well **during the assignment** from one to another. If you are multiplying two smaller types that may result in a number that needs a larger type to be represented, **there is no automatic type promotion**.

int appleValue= 55;
int appleCount = 2000 * 1000 * 1000;
long appleNetWorth …;
appleNetWorth = appleValue * appleCount; // WRONG RESULT, TYPE OVERFLOW!
appleNetWorth = (long) (appleValue * appleCount); // WRONG RESULT, TYPE OVERFLOW!
appleNetWorth = (long) appleValue * appleCount; // Nefariously correct!
long appleNetWorth = (long)appleValue * (long)appleCount; // Verbosely correct!

Use “Number.toString” to convert numbers to strings

Whether you should be always using java.text.NumberFormat depends on your particular purpose at the time, but otherwise use the static “toString” method for the corresponding numeric type. Avoid constructs like this:

String appleValueStr…;
appleValueStr = "" + appleValue; // BAD: It works...at a cost…
appleValueStr = Integer.toString(appleValue); // GOOD

This kind of construct has two obvious problems, the first being that I will be mad at you due to the second problem, which is the wasteful creation of an additional String to contain the result of the concatenation.

Avoid constructing Number instances.

Number is the base type for Integer, Long, Float, and other numeric types. Creating a new number using its constructor inhibits JRE optimizations where the most common numbers (-128 to 128) are cached.

Integer appleValueObject = ...;
appleValueObject = new Integer(appleValue); // BAD: Prevents memory optimization
appleValueObject = Integer.valueOf(appleValue); // GOOD: May save you some memory for small numbers

No comments:

Post a Comment