4

What is the difference between the following two, and which is more preferable??

public class foo {

    int i = 2;

}

public class foo {

  int i;
    foo() {

        i = 2;

    }
}
user1976547
  • 79
  • 1
  • 5
  • Consider correcting the error in your example, as it does not reflect your question title. – Perception Feb 25 '13 at 11:32
  • Sorry. Just corrected the mistake. – user1976547 Feb 25 '13 at 11:37
  • If you have used an Object type instead of using a primitive type, then if you initialize the variable at declaration, what you are going to do if an exception occurs at the initialization of the variable ? Use constructors, that's why they are invented. And if you have to init variables that needs no parameters, put them in your no-arg constructors. If you are going to add additional parameter constructors, then chain the constructors which is called as "telescoping constructors" so you will not have to repeat your code. – Levent Divilioglu May 09 '16 at 03:07

5 Answers5

4

In your example, there is no difference in behavioural semantics. In Java, all instance field initializers (and instance blocks) are executed after superclass initialization, and before the body of the constructor; see JLS 12.5.

The difference lies in code readability and (in other examples) avoiding repetitious coding and fragility1. These need to be assessed on a case-by-case basis.

It is also worth noting that there are some cases where you have to initialize in the constructor; i.e. when the initialization depends on a constructor parameter.


1 - The repetitiousness and fragility issues are flip-sides of the same thing. If you have multiple constructors, the "initialize in constructor" approach tends to lead to repetition. And if you add extra fields, you might to add the initialization to all relevant constructors; i.e. fragility.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • +1. You might want to provide some background as to ***why*** the two are functionally the same, maybe by illustrating the class initialization process. – Perception Feb 25 '13 at 11:57
1

If you have two or more constructors and intialization value differs in each of them, then you should use constructor initialization as there is no way to do the same with member initialization...

however if you have just one constructor...you can use member initialization for better code clarity..

MayurB
  • 3,609
  • 2
  • 21
  • 36
0

In your first example, i is an instance variable of class foo (better name would be Foo). It's initialised at class loading.

In your second example, i is also an instance varaible but in this case initialised in the foo() constructor.

There is no real difference here, and especially with primitives.

However, in a multi-threaded environment, if you do intend to initialise your ivars in your constructor, and those ivars are non-primitive, you need to avoid the risk of exposing a partially constructed object. The reason for this is that constructors aren't synchronised and can't have the synchronised keyword applied but then two threads can't be constructing the same object.

So, to avoid this, you should never expose this in your constructor. One way of doing so is to call non-final methods. Doing so, say calling an abstract method, allows some unknown code to do something with your unfinished object. Obviously, this can't be done if you initialise in your declaration.

p.s. I thought there was something on this in Effective Java but couldn't find anything.

wmorrison365
  • 5,995
  • 2
  • 27
  • 40
0

First of all I think the second example should look like this:

public class foo{

  int i;
  foo(){

     i = 0;

  }

}

Otherwise i is just a local variable in the C'tor scope. Second, the first example shows initialization which is called before the class C'tor is invoked. this is good if you want this to happen no matter what C'tor is used. It also enables you to declare i as readonly.

omer schleifer
  • 3,897
  • 5
  • 31
  • 42
0

In particular this case there is no difference in these two variants. First variant is more preferable, because initializations of fields inside constructor, as usual, use external values from constructor arguments.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241