Before I ask the question I like to provide the code for clarity. Below is my code for singleton class.
public class CoreData {
private boolean VarA;
private static CoreData instance = null;
protected CoreData() {
// Exists only to defeat instantiation.
}
public static CoreData getInstance() {
if(instance == null) {
instance = new CoreData();
}
return instance;
}
public boolean getVarA(){
return VarA;
}
public void setFirstTime(boolean B){
VarA = B;
}
}
Now I have few questions to ask
- What will be difference if make the member variable VarA as static?
- Can I initialize the member variable in the method getInstance()?
- What is the best practice in initializing member variables in Singleton class?
- What is the meaning of making this class as final?
- What is the meaning of making the member variable final.
I am very new to java and OOPS. I am learning it now. I would be grateful if someone answer my queries to make my knowledge better.
What will be difference if make the member variable VarA
as static
?
It will be harder to make it non singleton later
Can I initialize the member variable in the method getInstance()
?
Yeah. Why not. But actually constructors are done for this.
What is the best practice in initializing member variables in Singleton class?
By the best practice you should use some IoC and don't put any code about scope in your logic code.
What is the meaning of making this class as final?
You should use private
constructor instead of protected
one or make it final
to prevent creating several instances by extending. Like new CoreData(){};
What is the meaning of making the member variable final?
I believe all variables should be final by default. Also it can help you with multi threading issues.
Because you've only got one instance (or so you think - see below) making it static shouldn't make any difference.
Your code is not threadsafe! You could have two instances created. The reason is, after checking instance is null, another thread could also check and find it null - both threads would create instances and return them. One would "escape".
The traditional approach was "double checked locking", where the check is made inside a synchronized block, but as Bill Pugh pointed out in his famous article, that is a broken pattern. Java 1.5 introduced the volatile
keyword to work around this problem, but it's still ugly code.
The modern best practice approach to lazy initialize the instance, is to use one of these patterns:
public class CoreData {
private static class InstanceHolder {
static CoreData INSTANCE = new CoreData();
}
public static CoreData getInstance() {
return InstanceHolder.INSTANCE;
}
}
or
public static enum CoreData {
INSTANCE;
// rest of class
}
Both are guaranteed by the language to create singletons, but the enum version is "iron-clad " - it is possible through a deserialization hack to affect the instance's state in the static holder class pattern. Apart from that slim vulnerability, both work. I prefer the first option in my code simply because it avoids class bloat.