8

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?

0

4 Answers 4

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;
  }

}
Sign up to request clarification or add additional context in comments.

3 Comments

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 - In that case, no I would initialize it when it is declared, and I would declare it to be final.
I can see the reason for making it final in your example, but what if there was a setter setName( String name )...
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.

6 Comments

the first works just fine for none static fields. it's a syntatic sugar for the 2nd.
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.
I see no reason to reserve the first style for static variables. Can you provide any reasoning?
Another reason is that such a declaration could be confused with a constant declaration.
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
|
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.

1 Comment

We can use initialization blocks to initialize fields which would otherwise only be initialized inside a method or constructor.
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;
        }
    }
}

2 Comments

Actually one could also use an initializer block here, so the constructor is not the only possible way even in this case
Yes, that might be too confusing though. But that's my opinion. Will edit.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.