Singleton java pattern
I can still instantiate by using constructor although in class definition it has been declared as private constructor??? Here is code snippet:
public class Singleton {
private static Singleton instance;
private String name;
/* Private constructor prevents other classes from instantiating */
private Singleton(String name) {
this.name = name;
// Optional code
}
/*
* Static factory method that creates instance instead of constructor.
* Synchronization helps to block any attempt to instantiate from simultaneous
* thread hence break concept of singleton.
* This method uses a technique known as lazy instantiation.
*/
public static synchronized Singleton getInstance(String name) {
if (instance == null) {
instance = new Singleton(name);
}
return instance;
}
/* Override Object clone method to avoi开发者_如何学JAVAd cloning */
@Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
public String getName() {
return name;
}
/* Example of using singleton object */
public static void main(String[] args) {
Singleton a = new Singleton("Hoang");
Singleton b = new Singleton("Shiha");
System.out.println(a.getName());
System.out.println(b.getName());
}
You can still instantiate it because your test main() method, being in the same class, has access to the private constructor: private means "only available to this class".
Put your test in another class, and you'll get what you expect.
Your test method is within the same class -> it has access to private members & methods.
Refer to this question for more info on the Singleton pattern in Java :)
You are able to instantiate the singleton because you are doing it from a method inside the Singleton's class definition (hint, you can access private methods within the class that define them.
Try doing that from outside your Singleton, and it will fail. On another note, Singleton are typically defined as final (very rare that you legitimately need to extend a Singleton class).
On another note, one typically puts some sort of guard condition (.ie. throwing a UnsupportedOperationException) on the default (and private) constructor to defend against accidental (or malicious attack) access to it via reflection.
/* default constructor made private and defended against reflection access */
private Singleton() {
throw new UnsupportedOperationException("naughty boy");
}
To be sure to instanciate it just once, you may use the Singleton Enum pattern:
public enum MySingleton {
INSTANCE("My singleton name");
private MySingleton(String name) {
this.name = name;
}
private String name;
public String getName() {
return this.name;
}
}
An enum is in some way a list of singletons sharing the same interface
精彩评论