July 13, 2007
Enterprise Systems: The New Bounce in Suns Step. Dont look now, but Sun Microsystems Inc. has a new bounce in its step.
From its recent...
More »
June 24, 2007
Jazoon'07. Jazoon'07 brings together experts and users of Java and open source technologies from all...
More »
|
 |
Code Advice #14: Don't initialize fields to default values
(See intro for a background and caveats on these coding advice blog entries.)
If you've been coding in C, you've probably picked up the habit of initializing all your fields:
char *foo = NULL;
int bar = 0;
This is necessary, because in C, memory can be left uninitialized, so there's no telling what value foo will have before it is assigned something.
In Java, however, the language specification clearly defines default values, so virtual machines will for example always initialize reference fields to null.
Specifically, this means that code like the following is redundant:
private int foo = 0;
private Bar bar = null;
private boolean baz = false;
The alternative form of initializing the fields explicitly in the constructor, is the same:
private int foo;
private Bar bar;
private boolean baz;
public Foo() {
foo = 0;
Bar bar = null;
baz = false;
}
You can leave out the above initializations, and the program will behave the same way. Carl Quinn once convinced me that this was more readable, so I picked up the habit, and I now swear by it. On the one hand, you can argue that leaving the explicit initializations in is more readable because you're making it really clear what it is you are intending. On the other hand, Java programmers quickly learn what the default values are and understand that an uninitialized field is the same as a nulled out field.
It turns out that the two forms are not exactly identical! If you disassemble the above code, you'll find the following bytecode is generated:
4: aload_0
5: iconst_0
6: putfield #2; //Field foo:I
9: aload_0
10: aconst_null
11: putfield #3; //Field bar:LBar;
14: aload_0
15: iconst_0
16: putfield #4; //Field baz:Z
If you leave out the initializations, none of the above bytecode is generated. In a simple microbenchmark there was a measurable time difference (about 10%) for the case where a handful of fields were initialized versus leaving them uninitialized, so it's clear that Hotspot doesn't completely eradicate the differences here. (Perhaps it just zeroes out the whole object memory block when allocating a new object, relying on the default values to all be represented as zeroes natively, and this is done even when all fields are later initialized?)
Obviously, speed considerations is not what should be the deciding factor here. This was a microbenchmark doing nothing other than construct objects with and without initialization - it's unlikely that you'll find a measurable difference on a real program. What really matters is readability. I should also point out that Findbugs will treat these two scenarios differently. If you print out a field value in the constructor, it will warn about an uninitialized field if the field was not explicitly initialized in the field declaration.
I can see arguments both for and against explicit field initialization, but I think this is one of those cases where convention wins. I personally find code cleaner and more readable when you leave your fields with implicit rather than explicit initialization.
P.S. Remember that null fields are often a bad idea and should be initialized to null-objects!
Date: October 16, 2006
Category: Developers
More »
Others News
|