Is there any advantage for either approach?
Example 1:
class A {
B b = new B();
}
Example 2:
class A {
B b;
A() {
b = new B();
}
}
Is there any advantage for either approach?
Example 1:
class A {
B b = new B();
}
Example 2:
class A {
B b;
A() {
b = new B();
}
}
Another option would be to use Dependency Injection.
This removes the responsibility of creating the
B
object from the constructor ofA
. This will make your code more testable and easier to maintain in the long run. The idea is to reduce the coupling between the two classesA
andB
. A benefit that this gives you is that you can now pass any object that extendsB
(or implementsB
if it is an interface) toA
's constructor and it will work. One disadvantage is that you give up encapsulation of theB
object, so it is exposed to the caller of theA
constructor. You'll have to consider if the benefits are worth this trade-off, but in many cases they are.There is additionally the initialization block, which is as well put in the constructor(s) by the compiler:
Check Sun's explanation and advice
From this tutorial:
Additionally, you might want to lazily initialize your field. In cases when initializing a field is an expensive operation, you may initialize it as soon as it is needed:
And ultimately (as pointed out by Bill), for the sake of dependency management, it is better to avoid using the
new
operator anywhere within your class. Instead, using Dependency Injection is preferable - i.e. letting someone else (another class/framework) instantiate and inject the dependencies in your class.Both of the methods are acceptable. Note that in the latter case
b=new B()
may not get initialized if there is another constructor present. Think of initializer code outside constructor as a common constructor and the code is executed.Using either dependency injection or lazy initialization is always preferable, as already explained thoroughly in other answers.
When you don't want or can't use those patterns, and for primitive data types, there are three compelling reasons that I can think of why it's preferable to initialize the class attributes outside the constructor:
The second option is preferable as allows to use different logic in ctors for class instantiation and use ctors chaining. E.g.
So the second options is more flexible.
I got burned in an interesting way today:
See the mistake? It turns out that the
a = null
initializer gets called after the superclass constructor is called. Since the superclass constructor calls init(), the initialization ofa
is followed by thea = null
initialization.