[java] Should I initialize variable within constructor or outside constructor

When I use Java based on my C++ knowledge, I love to initialize variable using the following way.

public class ME {
    private int i;

    public ME() {
         this.i = 100;
    }
}

After some time, I change the habit to

public class ME {
    private int i = 100;

    public ME() {
    }
}

I came across others source code, some are using 1st convention, others are using 2nd convention.

May I know which convention do you all recommend, and why?

This question is related to java

The answer is


I think both are correct programming wise,

But i think your first option is more correct in an object oriented way, because in the constructor is when the object is created, and it is when the variable should initialized.

I think it is the "by the book" convention, but it is open for discussion.

Wikipedia


Both the options can be correct depending on your situation.

A very simple example would be: If you have multiple constructors all of which initialize the variable the same way(int x=2 for each one of them). It makes sense to initialize the variable at declaration to avoid redundancy.

It also makes sense to consider final variables in such a situation. If you know what value a final variable will have at declaration, it makes sense to initialize it outside the constructors. However, if you want the users of your class to initialize the final variable through a constructor, delay the initialization until the constructor.


I have the practice (habit) of almost always initializing in the contructor for two reasons, one in my opinion it adds to readablitiy (cleaner), and two there is more logic control in the constructor than in one line. Even if initially the instance variable doesn't require logic, having it in the constructor gives more flexibility to add logic in the future if needed.

As to the concern mentioned above about multiple constructors, that's easily solved by having one no-arg constructor that initializes all the instance variables that are initilized the same for all constructors and then each constructor calls this() at the first line. That solves your reduncancy issues.


The only problem I see with the first method is if you are planning to add more constructors. Then you will be repeating code and maintainability would suffer.


It can depend on what your are initialising, for example you cannot just use field initialisation if a checked exception is involved. For example, the following:

public class Foo {
    FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException
}

Will cause a compile-time error unless you also include a constructor declaring that checked exception, or extend a superclass which does, e.g.:

public Foo() throws FileNotFoundException {} 

I would say, it depends on the default. For example

public Bar
{
  ArrayList<Foo> foos;
}

I would make a new ArrayList outside of the constructor, if I always assume foos can not be null. If Bar is a valid object, not caring if foos is null or not, I would put it in the constructor.

You might disagree and say that it's the constructors job to put the object in a valid state. However, if clearly all the constructors should do exactly the same thing(initialize foos), why duplicate that code?


One thing, regardless of how you initialize the field, use of the final qualifier, if possible, will ensure the visibility of the field's value in a multi-threaded environment.


I recommend initializing variables in constructors. That's why they exist: to ensure your objects are constructed (initialized) properly.

Either way will work, and it's a matter of style, but I prefer constructors for member initialization.


I tend to use the second one to avoid a complicated constructor (or a useless one), also I don't really consider this as an initialization (even if it is an initialization), but more like giving a default value.

For example in your second snippet, you can remove the constructor and have a clearer code.


If you initialize in the top or in constructor it doesn't make much difference .But in some case initializing in constructor makes sense.

class String
{
    char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.
    String()
    {
        this.arr=new char[0];
    }
    String(char[] arr)
    {
        this.arr=arr;
    }
}

So depending on the situation sometime you will have to initialize in the top and sometimes in a constructor.

FYI other option's for initialization without using a constructor :

class Foo
{
    int i;
    static int k;

    //instance initializer block
    {
        //run's every time a new object is created
        i=20;
    }

    //static initializer block
    static{
        //run's only one time when the class is loaded
        k=18;
    }    
}