what is difference between following variable usages
public class A{
B b= new B();
public void doSomething()
{
b.callme();
}
}
The first case is called inline initialization. It will happen before the body of any constructors run but after the call to the super constructor.
In the second case b is not initialized until doSomething is called().
As for which is better, that depends on your program logic. If you want a new instance every time doSomething is called, the second way is better. If you'd prefer to lazy load b then modify it to be
if (b == null) b = new B();
return b;
Personally I generally allocate instance variables in the constructor for the sake of readability.
public class A {
B b;
public A() {
b = new B();
}
}
The REAL difference here is that do you want a different instance of B
each time doSomething
is called? In the second case this is true but it also means that your class is not thread-safe if there are any other methods using B
. And if there are NOT any other methods in the class using B
why not make it a method-scoped variable?
I was just trying out a similar scenario, but due to a mistake I created a scenario for recursion instead (StackOverflow error):-
public class Test{
Test t=new Test();
public static void main(String[] args) {
Test t=new Test();
System.out.println("Hello");
}
}
I think it might be helpful to some for the conceptual purpose.
Class level instantiation
will instantiate your class variables when new object of your class is created. While method instantiation
will instantiate your variables when the method is invoked.
Good Practice : You should do Class level instantiation
or instantiate in Constructor
when your class variable is/must be final
or else use method instantiation
i.e lazy initialization
Case 2:
Is helpful for lazy initialization
In case 1
the object of B
is created when you create object of A
. But if creating B
is heavy operation then you can lazily create it when you actually need B instance.
Lazy Initialization
is helpful when the creating the object is a heavy task and you want to lazily create the object instance only when it is actually being used. But do take care of thread safety
if your class is being shared between threads.
UPDATE: But in your case you are reassigning the reference b everytime the method is called. Which is not Lazy initialization per se.
//example of lazy initialization
public B getB()
{
if (something = = null)
b = new B();
return b;
}
These actually have very different meanings. In case 1, the b
object is assigned when A
is constructed. It is constructed once and only once (unless you are reassigning it from somewhere outside the class).
In case 2, you are reassigning A's
instance of b
every time the method is invoked