views:

118

answers:

3

Let's say I have this:

public class Whatever {
   private ArrayList<String> myList = new ArrayList<String>();
   // more code goes here
}

or let's say I have this:

public class Whatever {
   private ArrayList<String> myList = null;

   public Whatever() {
     myList = new ArrayList<String>();
   }
}

What's the difference between these two initialisations of myList? Would it be wrong to preffer the first variant?

+13  A: 

The first variant will always instantiate the array list, the second one only when calling the default constructor. Meaning for the second solution you will have to call the default constructor for any additional constructor you add e.g.

public class Whatever {
   private final List<String> myList;

   public Whatever() {
     myList = new ArrayList<String>();
   }

   public Whatever(String name) {
     this();
     // Other stuff done
   }

   public Whatever(List<String> myList) {
     this.myList = myList;
   }
}

The (second) "lazy" initialization method might be better if you don't always use the list (e.g. if you set the list in another constructor directly like in my example) and want to avoid creating unnecessary objects. (EDIT: I changed the ArrayList to an interface and set it final. It wasn't part of the question but it is - as mentioned in the comments - the best way to use List collections).

Daff
+3  A: 

The JVM first executes code such as this (outside the constructor):

public class Whatever {
   private ArrayList<String> myList = new ArrayList<String>();
   // more code goes here
}

And only then code such as this (inside the constructor):

public class Whatever {
   private ArrayList<String> myList = null;

   public Whatever() {
     myList = new ArrayList<String>();
   }
}

So unless the order of execution is somehow important to you i guess @Daff's answer is the right one.

Yaneeve
+3  A: 

In this particular example, there is no difference except that the first form is shorter.

However, if the attribute initialization expression (potentially) throws exceptions, the second form allows you to catch the exceptions, or declare them as thrown in the constructor signature.

And of course, if you have multiple constructors, the second form allows you to initialize the attribute differently in each constructor ... or use constructor chaining to initialize the attribute the same ... or mix the two styles of initialization.

Stephen C