Raunak Agarwal
Raunak Agarwal

Reputation: 7228

Instance Variable Declaration and instantiation

I want to know what is the difference between these two ways of instantiating instance variable. In either case it would create an instance of the persons when an instance of PersonDirectory is created.

public class PersonDirectory {
    private ArrayList<Person> persons = new ArrayList<>();

}


public class PersonDirectory {
    private ArrayList<Person> persons;
    public PersonDirectory(){
        persons = new ArrayList<Person>();
    }
}

Upvotes: 3

Views: 3782

Answers (3)

Mike Clark
Mike Clark

Reputation: 10136

They are so similar that for basic programming they could be considered equivalent. The most obvious thing you might notice is when you add another constructor to PersonDirectory, like so:

public class PersonDirectory {
    private ArrayList<Person> persons;
    private DirectoryAdmin admin;
    public PersonDirectory() {
        persons = new ArrayList<Person>();
    }
    public PersonDirectory(DirectoryAdmin initialAdmin) {
        admin = initialAdmin;
    }
}

If you utilize this second constructor, you would find that persons is null after constructing PersonDirectory. This is because Java does not run other constructors for you automatically. You could fix the problem by adding an explicit call to this(), which runs also the constructor that matches the signature of the this call.

public class PersonDirectory {
    private ArrayList<Person> persons;
    private DirectoryAdmin admin;
    public PersonDirectory() {
        persons = new ArrayList<Person>();
    }
    public PersonDirectory(DirectoryAdmin initialAdmin) {
        this();
        admin = initialAdmin;
    }
}

But often times programmers forget to add the call to this(); and may find out too late that persons has been left null because one of their constructors was written carelessly.

If you instead write the initialization inline with the declaration, the initialization is run regardless of which PersonDirectory constructor you call, and so could be considered slightly less error-prone.

public class PersonDirectory {
    private ArrayList<Person> persons = new ArrayList<Person>();
    private DirectoryAdmin admin;
    public PersonDirectory() {
    }
    public PersonDirectory(DirectoryAdmin initialAdmin) {
        // don't have to worry about forgetting to call this();
        admin = initialAdmin;
    }
}

There are, however, reasons to sometimes prefer initialization in the constructor. For example, it can give more control to subclasses and their constructors.

It is a good practice to declare your member variables final whenever possible. This way the compiler can remind you if you've written a constructor that leaves some fields uninitialized.

Inline initialization statements always run before the class's constructor(s).

Upvotes: 4

liuzhijun
liuzhijun

Reputation: 4469

class loading and initialization sequence

  1. static statements/static blocks are executed

  2. Instance variables are assigned default [v][1]alues

  3. Instance variables are initialized
  4. constructor runs
  5. Instance initialization block(s) run after all the call(s) to super has(have) been completed but before the rest of the constructor is executed.
  6. Rest of the constructor is executed.

    http://www.coderanch.com/t/267125/java-programmer-SCJP/certification/Initializing-Sequence

Upvotes: 0

Jeroen Vannevel
Jeroen Vannevel

Reputation: 44439

Both are equal. Slight edge cases arise once you start adding more elements:

  • Constructor overloading can make the initialization inconsistent (first one uses new X, another uses new Y, another doesn't use it at all)

  • The field might require additional computation -> constructor is more suited

  • Static field values shouldn't be assigned in a constructor

Upvotes: 0

Related Questions