8

Possible Duplicate:
Should I initialize variable within constructor or outside constructor

I was wondering, which is a better practice and why. Should I initialize class fields upon declaration, or should I do it in the constructor? Given that it's a simple one-line initialization.

class Dude
{
    String name = "El duderino";

    Dude() {
        // irrelevant code
    }
}

vs.

class Dude
{
    String name;

    Dude() {
        name = "El duderino";

        // irrelevant code
    }
}

Edit: I am aware of the situations where one of the styles would be preferred over the other like in the case of executing initializer code that might throw an exception. What I'm talking about here are cases when both styles are absolutely equivalent. Both ways would accomplish the same task. Which should I use then?

Community
  • 1
  • 1
amrhassan
  • 2,285
  • 3
  • 16
  • 12

4 Answers4

5

If the member can only be set via an accessor (a "setter" method), I prefer the first style. It provides a hint that the initialized value is the default upon construction.

If the member can be specified during construction, I generally pass the default value to an appropriate constructor from constructor with fewer parameters. For example,

final class Dude {

  private final String name;

  Dude() {
    this("El Duderino");
  }

  Dude(String name) {
    this.name = name;
  }

}
erickson
  • 265,237
  • 58
  • 395
  • 493
  • This sounds reasonable. But what I was talking about are fields that were going to be initialized the same either way, i.e. data retrieved from constructors wouldn't be used. Like initializing an empty internal List for storing sub-elements. Would you still initialize it in the constructor? – amrhassan Aug 09 '11 at 22:39
  • @amrhassan - In that case, no I would initialize it when it is declared, and I would declare it to be `final`. – erickson Aug 09 '11 at 22:43
  • I can see the reason for making it `final` in your example, but what if there was a setter `setName( String name )`... – knownasilya Oct 11 '12 at 18:08
0

The first one is used usually to initialize static variable and should be used only for that purpose.

In this case, you should use the second method.

Please correct me if I am wrong.

mmtauqir
  • 8,499
  • 9
  • 34
  • 42
  • the first works just fine for none static fields. it's a syntatic sugar for the 2nd. – amit Aug 09 '11 at 22:06
  • Yeah I know what you mean. But if you have used C++, you will know that there is no such thing as what he did in the first one to initialize static variables and this was added to java for this exact purpose - initializing static variables. Therefore, it must be used for the purpose it was made for. – mmtauqir Aug 09 '11 at 22:08
  • I see no reason to reserve the first style for static variables. Can you provide any reasoning? – erickson Aug 09 '11 at 22:09
  • Another reason is that such a declaration could be confused with a constant declaration. – mmtauqir Aug 09 '11 at 22:11
  • I disagree. Using the constructor means that a) one doesn't see the value of the variable at first glance (has to look at all constructors to see if it is always initialized to the same value) and b) you have to write the initialization for each and every constructor you write. DRY – Voo Aug 09 '11 at 22:13
  • Check the marked duplicate question. These two approaches are equivalent, although you could argue a preference on stylistic grounds. – Mike Tunnicliffe Aug 09 '11 at 22:14
0

It is best to declare variables inside the constructor for the sake of consistency. A variable may require something like a loop or an if-else statement to initialize it, which can not be done in the declaration without placing the operation inside of a method.

The exception to this rule is static variables, which should be declared outside of the constructor.

CalMlynarczyk
  • 705
  • 2
  • 7
  • 12
  • We can use initialization blocks to initialize fields which would otherwise only be initialized inside a method or constructor. – emory Aug 09 '11 at 22:20
0

Single-line declarations cannot contain complex initialization logic.

If you initialize a variable as:

class AnotherClass
{
    MyClass anObject = new MyClass(); //MyClass() throws a checked exception.
}

then you'll find that you cannot provide the initial value in the single line. You'll need to place such code in a block, that quite obviously goes inside a constructor (or in a non-static initialization block):

Using a constructor:

class AnotherClass
{
    MyClass anObject;

    AnotherClass()
    {
        try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
    }
}

Using a initialization block:

class AnotherClass
{
    MyClass anObject;

    {
        try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
    }
}

I find that the latter makes for less understandable code, as the declaration and initialization are separated from each other, and the initialization does not occur in a constructor coded by the developer (although there is no difference at runtime).

The same goes for other complex routines involved in initialization of fields. For example, if you intend to initialize an Array or a Collection and set the contents of the array/collection to some default value, then you should do so inside a constructor:

class AnotherClass
{
    Integer[] integers;

    AnotherClass()
    {
        this.integers = new Integer[10];
        for(Integer integer: integers)
        {
            integer = Integer.MIN_VALUE;
        }
    }
}
Vineet Reynolds
  • 76,006
  • 17
  • 150
  • 174