Presents your JAVA E-NEWSLETTER for July 10, 2003 <-------------------------------------------> WHEN INITIALIZED ISN'T What's the output of the following code? import java.util.ArrayList; public class InitializationTip { public static void main(String args[]) { new B(); } public InitializationTip() { foo(); } protected void foo() { // do some init work here } } class B extends InitializationTip { private ArrayList list = new ArrayList(); public B() { foo(); } protected void foo() { System.out.println(list); } } A) [] B) [] [] C) null[] The correct answer is C, and the explanation is anti-climatic. What's happening is that when the instance of B is created, its constructor is called, and in turn, the superclass's no argument constructor is being invoked. The rule is that if a specific superclass constructor isn't called from the child class's constructor, then the compiler inserts a call to the superclass's default constructor. You can see this by looking at the decompiled bytecode for the B class. Method B() 0 aload_0 1 invokespecial #1 4 aload_0 5 new #2 8 dup 9 invokespecial #3 12 putfield #4 15 aload_0 16 invokevirtual #5 19 return A call is made to the InitializationTip's constructor on line 1 of B's constructor. This call is made before the assignment is made to the list field. The problem occurs in the constructor for InitializationTip when it makes a call to the protected member function foo(). foo() is protected, and therefore, it can and is overridden by the subclass B. Since the overridden method foo() in B accesses the instance variable list, and the list has yet to be assigned a value by the constructor, the resulting output is null. After program execution exits the superclass's constructor, the assignment is made to list, foo() is called by B's constructor, and all goes as expected. What's the lesson? Don't call overrideable methods from constructors. You have no idea what an overriding class may do in that overridden method. In this case, not much went wrong, but the bugs created by this kind of programming can be subtle and hard to track down. Save yourself a lot of time and effort by following the simple rule of not calling overrideable methods from constructors. David Petersheim is a Senior Java Developer with Genscape, Inc. He designs and develops server-side applications to acquire and process real-time energy data. ----------------------------------------