@Documented @Retention(value=RUNTIME) @Target(value=TYPE) public @interface Singleton
The recommended implementation approach, by Bloch, is to use the enum
singleton implementation pattern, this implies
enum has only a single element that is recommended, but not
mandated, to be called INSTANCE.Three implementation approaches are allowed if the singleton is implemented as a class. All require that the class is declared final and that the constructor is private. Further, if the singleton class is serializable then it must
The second implementation pattern uses a private static final field to hold the singleton reference and a public static method to obtain the instance. The recommended, but not mandated, field name is INSTANCE. The recommended, but not mandated, method name is getInstance.
The third implementation pattern uses the lazy initialization holder class idiom described by Joshua Bloch in Effective Java (Second Edition) (Addison-Wesley 2008) Item 71. In this approach the singleton contains a private static class that holds the reference to the singleton object in a static final field. The recommended, but not mandated, nested class name is LazyInitilizationHolder. The singleton contains a public static method to obtain the instance. The recommended, but not mandated, field name is INSTANCE. The recommended, but not mandated, method name is getInstance.
Access to the singleton object via INSTANCE or getInstance is multi-thread safe. Note that this does not mean that the singleton's state is thread safe—it may be or it may not be—just that access to the reference is safely shared if clients use INSTANCE or getInstance to obtain the reference to the singleton.
It is a modeling error to apply this annotation to an interface.
enum singleton implementation pattern is shown in
the code below.
@Singleton
public enum Elvis {
INSTANCE;
private int age;
public int getAge() {
return age;
}
public void setAge(int value) {
age = value;
}
}
An example of the public static field singleton implementation
pattern is shown in the code below.
@Singleton
public final class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
// only one
}
private int age;
public int getAge() {
return age;
}
public void setAge(int value) {
age = value;
}
}
An example of the private static field singleton implementation
pattern is shown in the code below.
@Singleton
public final class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
// only one
}
public static Elvis getInstance() {
return INSTANCE;
}
private int age;
public int getAge() {
return age;
}
public void setAge(int value) {
age = value;
}
}
An example of a singleton that is serializable. This approach is supported,
but not recommended, use the enum implementation pattern
instead.
@Singleton
public final class Elvis implements Serializable {
private static final long serialVersionUID = -5264712062432607599L;
private Object readResolve() {
return INSTANCE;
}
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
// singleton
}
public static Elvis getInstance() {
return INSTANCE;
}
private transient int age;
public int getAge() {
return age;
}
public void setAge(int value) {
age = value;
}
}
An example of the lazy initialization singleton implementation pattern is
shown in the code below.
@Singleton
public final class Elvis {
private static class LazyInitilizationHolder {
private static final Elvis INSTANCE = new Elvis();
}
private Elvis() {
// only one
}
public static Elvis getInstance() {
return LazyInitilizationHolder.INSTANCE;
}
private int age;
public int getAge() {
return age;
}
public void setAge(int value) {
age = value;
}
}
@annotate tag.
/**
* @annotate Singleton
*/
public final class Elvis {
...
}
Copyright © 2012 Surelogic, Inc.. All Rights Reserved.