264

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?

Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • 2
    You should initialize using initialization lists in C++. Otherwise it's initialization + assignment. – Vsevolod Golovanov Jul 12 '12 at 09:46
  • 2
    This is a duplicate of http://stackoverflow.com/q/1994218/922348. See accepted answer for more thorough discussion. – rimsky Dec 14 '12 at 17:57
  • They have already default value... no need to Init them AGAIN. – Yousha Aleayoub Sep 11 '16 at 02:26
  • What I wish Java had was things from functional programming like: Car myCar = new Tesla.ModelY(){ setRange(1); setLeather(true); /*etc*/}; But at least we can use the builder pattern and have setters return this; eg Car myCar = Tesla.ModelY.newInstance().setRange(1).setLeather(true).setOther(thing).build(); – Skystrider Aug 03 '23 at 20:54

11 Answers11

258

I find the second style (declaration + initialization in one go) superior. Reasons:

  • It makes it clear at a glance how the variable is initialized. Typically, when reading a program and coming across a variable, you'll first go to its declaration (often automatic in IDEs). With style 2, you see the default value right away. With style 1, you need to look at the constructor as well.
  • If you have more than one constructor, you don't have to repeat the initializations (and you cannot forget them).

Of course, if the initialization value is different in different constructors (or even calculated in the constructor), you must do it in the constructor.

sleske
  • 81,358
  • 34
  • 189
  • 227
  • 37
    To fix the second problem, I usually create a private constructor containing the code which would be repeated, and then call `this(privateConstructorArgs)` at the beginning of all other constructors. – atzol Aug 11 '15 at 00:58
  • 3
    Instead of defining and calling a private constructor from all other constructors, you could also define an instance initializer, which will automatically be called before every constructor. That way, you won't have to remember to call the private constructor, when you add some new constructors. – TheBaj May 04 '16 at 15:52
  • 1
    @TheBaj, since the private constructor suggestion was made to deal with needing to initialize the variable to different values depending on the constructor called, how would you tell from within the instance initializer which constructor was called to determine which value to assign? – Mike B Aug 04 '16 at 23:13
  • Great answer! What if I have a class with a field with a default value in style 2, but then I need to extend that class and want to have a different default for the subclass. Should I now use style 1 for the subclass and keep style 2 for the superclass? – EJS Oct 09 '17 at 14:56
  • @EJS: Hi, that sounds like a good separate question. Consider asking it as a new question :-). – sleske Oct 09 '17 at 16:53
  • What if I am not setting a default value but rather creating a data structure, eg. List list = new ArrayList(); Where should I put that? – Jan Horčička Jul 11 '19 at 16:35
  • @JanHorčička: I do not see a significant difference between `MyClass myField = new MyClass();` and `List list = new ArrayList();`. So just treat them the same. – sleske Apr 01 '22 at 07:37
33

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.

Joseph Cozad
  • 339
  • 3
  • 2
  • Even better than a no-arg constructor: an instance initializer block. If you're concerned about adding logic later, you could initialize everything in an instance initializer block so you don't have to call `this()` in your constructors. – Kaiser Keister Apr 26 '18 at 02:14
  • if construction of object requires logic -then it should be done in factory method, not in constructor. – magulla Oct 18 '18 at 00:25
  • @magulla not necessarily, if the object holds and enforce its rules, you can add logic in the constructor. Example, let's say a object "Temperature", where the constructor takes a float "value" and an enum "tempScale", where you check in the constructor that if TempScale = TempScale.Celsius and value < −273,15 then, you raise an exception, or automatically set the value to −273,15... Same for value < −459,67 and tempScale = Fahrenheit. You definitly don't need a factory for this. – Cromm Mar 25 '20 at 13:37
  • @Cromm yes, you can do that, but my point is that it is not a good practice, in my opinion: - if you have a logic, that is not related to actual construction, - if your logic can cause an exception, then you are opening a door to a potential usage of incomplete object reference. – magulla Jul 15 '20 at 13:49
  • Use Factories and POJOs for clean design. One class represents the structure of an object (POJO) and another class like Factory or helper or consumer or controller or anything that is smart and understands how to do things can manipulate the data of the POJO. Factories specifically for initializing the POJO which can include logic/conditions or configured data. – Skystrider Aug 03 '23 at 20:49
27

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.

nbro
  • 15,395
  • 32
  • 113
  • 196
Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
7

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;
    }    
} 
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
Emil
  • 13,577
  • 18
  • 69
  • 108
6

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.

Josmas
  • 147
  • 4
  • 20
    You can always chain your constructors. – Bernard Oct 12 '10 at 20:14
  • @Bernard chaining constructor + having inheritance can be really awful. – Colin Hebert Oct 12 '10 at 20:21
  • 5
    @Colin Hebert: It can be, but it can also be elegant if designed well. – Bernard Oct 12 '10 at 20:39
  • If you have multiple constructors, you can use telescoping constructors and chain them as @Bernard stated. The first one seem clearer at the first glance however, when you check a class, the first place you are going to look up will be the constructor(s) not the variables. Imagine you have a dozen of variables, why to init half of them at declaration and and half of the other on constructors instead of using telescoping constructors ? Use a no-arg constructor at first, then reference to no-arg constructors inside of the argument constructors, why not? This is why we use constructors. – Levent Divilioglu May 09 '16 at 03:02
6

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.

Bernard
  • 7,908
  • 2
  • 36
  • 33
4

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.

kasgoku
  • 5,057
  • 5
  • 20
  • 20
3

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.

Steve Emmerson
  • 7,702
  • 5
  • 33
  • 59
  • 1
    Really ? I think the final keyword has no impact on visibility when we talk about instance fields. A different story would be temporary fields (defined inside a method), then I would agree with you. But please give an example if I'm missing something. – bvdb Apr 29 '15 at 13:10
  • This is ok, but what does this have to do exactly with the question? The question to your answer would be: "How should I declare my fields and why?" – nbro May 08 '15 at 10:37
2

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

mklfarha
  • 983
  • 8
  • 13
1

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 {} 
Jonathan
  • 20,053
  • 6
  • 63
  • 70
0

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?

Ishtar
  • 11,542
  • 1
  • 25
  • 31