Can someone give me an example of when you'd use a private static field over a private static final field? I struggle to think of an example of when you'd want to declare a private class variable, that was subject to change.
Enter the Singleton pattern:
public class Clazz {
public static void main(String[] args) {
MyObject myObject = MyObject.getInstance();
}
}
class MyObject {
private static MyObject instance;
//I belong to the class, but I need not be created before somebody wants me.
private MyObject() {
}
public static MyObject getInstance() {
if (instance == null) {
instance = new MyObject();
}
return instance;
}
}
Yes.
For example when you want to have a counter variable to count how many objects have been created from a class, you'll make it static - it's associated with the class and not an object, but it's not final since it's changing:
protected static int counter = 0;
//constructor
counter++;
Worth mentioning note:
I didn't mention the Singleton example since if you want to be thread-safe, the variable must be static and final.
Related
My straight question is: does it still make sense consider Enum for singleton implementation since Reflection is now limited?
By singleton implemented throw enum I mean some implementation like:
public enum SingletonEnum {
INSTANCE;
int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
If we contrast the basic idea of modularity as mentioned in answer related to scope package access"... Jigsaw's accessibility rules now restrict access to public elements (types, methods, fields) only" and issue of reflexation fixed by enum we may wonder why still code singleton as enum.
Despite its simplicity, when serializing an enum, field variables are not getting serialized. On top of that enums do not support lazy loading.
To sum up, assuming I didn't say any foolish thing above, since the main advantage of using enum for singleton was protecting from reflection risks, I would reach the conclusion that coding a singleton as enum isn't anymore better than a simple implementation around static aproach like that:
When serialization is need
public class DemoSingleton implements Serializable {
private static final long serialVersionUID = 1L;
private DemoSingleton() {
// private constructor
}
private static class DemoSingletonHolder {
public static final DemoSingleton INSTANCE = new DemoSingleton();
}
public static DemoSingleton getInstance() {
return DemoSingletonHolder.INSTANCE;
}
protected Object readResolve() {
return getInstance();
}
}
When no serialization is involved neither is a complex object demanding lazy loading
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() {}
}
*** EDITED: added after #Holger comment regard serialization
public class DemoSingleton implements Serializable {
private static final long serialVersionUID = 1L;
private DemoSingleton() {
// private constructor
}
private static class DemoSingletonHolder {
public static final DemoSingleton INSTANCE = new DemoSingleton();
}
public static DemoSingleton getInstance() {
return DemoSingletonHolder.INSTANCE;
}
protected Object readResolve() {
return getInstance();
}
private int i = 10;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
public class DemoSingleton implements Serializable {
private volatile static DemoSingleton instance = null;
public static DemoSingleton getInstance() {
if (instance == null) {
instance = new DemoSingleton();
}
return instance;
}
private int i = 10;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
It’s not clear why you think that enum types were not lazily initialized. There is no difference to other class types:
public class InitializationExample {
public static void main(String[] args) {
System.out.println("demonstrating lazy initialization");
System.out.println("accessing non-enum singleton");
Object o = Singleton.INSTANCE;
System.out.println("accessing the enum singleton");
Object p = SingletonEnum.INSTANCE;
System.out.println("q.e.d.");
}
}
public enum SingletonEnum {
INSTANCE;
private SingletonEnum() {
System.out.println("SingletonEnum initialized");
}
}
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() {
System.out.println("Singleton initialized");
}
}
demonstrating lazy initialization
accessing non-enum singleton
Singleton initialized
accessing the enum singleton
SingletonEnum initialized
q.e.d.
Since the laziness is already there in either case, there is no reason to use a nested type as in your serializable singleton example. You could still use the simpler form
public class SerializableSingleton implements Serializable {
public static final SerializableSingleton INSTANCE = new SerializableSingleton();
private static final long serialVersionUID = 1L;
private SerializableSingleton() {
System.out.println("SerializableSingleton initialized");
}
protected Object readResolve() {
return INSTANCE;
}
}
The difference to an enum is that fields are indeed getting serialized, but there’s no point in doing so as after deserializing, the reconstructed object gets replaced with the current runtime’s singleton instance. That’s what the readResolve() method is for.
This is a semantic problem, as there can be an arbitrary number of different serialized versions but only one actual object, as otherwise it wouldn’t be a singleton anymore.
Just for completeness,
public class SerializableSingleton implements Serializable {
public static final SerializableSingleton INSTANCE = new SerializableSingleton();
private static final long serialVersionUID = 1L;
int value;
private SerializableSingleton() {
System.out.println("SerializableSingleton initialized");
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
protected Object readResolve() {
System.out.println("replacing "+this+" with "+INSTANCE);
return INSTANCE;
}
public String toString() {
return "SerializableSingleton{" + "value=" + value + '}';
}
}
SerializableSingleton single = SerializableSingleton.INSTANCE;
single.setValue(42);
byte[] data;
try(ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(single);
oos.flush();
data = baos.toByteArray();
}
single.setValue(100);
try(ByteArrayInputStream baos = new ByteArrayInputStream(data);
ObjectInputStream oos = new ObjectInputStream(baos)) {
Object deserialized = oos.readObject();
System.out.println(deserialized == single);
System.out.println(((SerializableSingleton)deserialized).getValue());
}
SerializableSingleton initialized
replacing SerializableSingleton{value=42} with SerializableSingleton{value=100}
true
100
So there’s no behavioral advantage in using an ordinary class here. Storing the fields contradicts the singleton nature and in the best case, these values have no effect and the deserialized object gets replaced by the actual runtime object, just like an enum constant is deserialized to the canonical object in the first place.
Also, there is no difference regarding lazy initialization. So the non-enum class requires more code to write to get with nothing better.
The fact that the readResolve() mechanism requires deserializing an object first, before it can be replaced by the actual result object is not only inefficient, it violates the singleton invariant temporarily and this violation is not always cleanly resolved at the end of the process.
This opens the possibility to the Serialization hack:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class TestSer {
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializableSingleton singleton = SerializableSingleton.INSTANCE;
String data = "’\0\5sr\0\25SerializableSingleton\0\0\0\0\0\0\0\1\2\0\1L\0\1at\0\10"
+ "LSneaky;xpsr\0\6SneakyOÎæJ&r\234©\2\0\1L\0\1rt\0\27LSerializableSingleton;"
+ "xpq\0~\0\2";
try(ByteArrayInputStream baos=new ByteArrayInputStream(data.getBytes("iso-8859-1"));
ObjectInputStream oos = new ObjectInputStream(baos)) {
SerializableSingleton official = (SerializableSingleton)oos.readObject();
System.out.println(official+"\t"+(official == singleton));
Object inofficial = Sneaky.instance.r;
System.out.println(inofficial+"\t"+(inofficial == singleton));
}
}
}
class Sneaky implements Serializable {
static Sneaky instance;
SerializableSingleton r;
Sneaky(SerializableSingleton s) {
r = s;
}
private Object readResolve() {
return instance = this;
}
}
SerializableSingleton initialized
replacing SerializableSingleton#bebdb06 with SerializableSingleton#7a4f0f29
SerializableSingleton#7a4f0f29 true
SerializableSingleton#bebdb06 false
Also on Ideone
As demonstrated, the readObject() returns the canonical instance as intended, but our Sneaky class provides access to the second instance of the “singleton” which was supposed to be of a temporary nature.
The reason why this works, is precisely because fields are serialized and deserialized. The specially constructed (sneaky) stream data contains a field which actually doesn’t exist in the singleton, but since the serialVersionUID matches, the ObjectInputStream will accept the data, restore the object and then drop it because there’s no field to store it. But at this time, the Sneaky instance got already hands on the singleton via a cyclic reference and remembers it.
The special treatment of enum types make them immune against such attacks.
Example class with singleton design pattern.
class Singleton {
private static Singleton instance;
private int x;
private Singleton() {
x = 5;
}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
public void doSomething() {
System.out.println("Hello");
}
}
I'm just wondering can I create this class with same variables and methods declared as static. Is it same as the singleton?
Singleton should be considered only if all three of the following criteria are satisfied:
Ownership of the single instance cannot be reasonably assigned
Lazy initialization is desirable
Global access is not otherwise provided for
Yes, It is the same.
If you really need to implement a singelton pattern I would recommend using an enum:
public enum MySingelton{
INSTANCE;
private final String[] variable = new String[]{"test", "test2};
public void randomFunction(){
}
}
Call it with:
MySingelton.INSTANCE.randomFunction();
With an enum implementation it's guaranteed that only one instance is created and that it's available all the time. Also it's possible to serialize and deserialize the singelton without creating multiple copies of it.
More information can be found here:
What is an efficient way to implement a singleton pattern in Java?
http://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=3
Since the purpose of the singleton pattern is to ensure that a single instance of a class exists, yes, you could use static members to achieve the same effect.
So instead of
public class Singleton {
private static Singleton theInstance = new Singleton();
private int aVar = 10;
public void aMethod() {
System.out.println(aVar);
}
public static Singleton getInstance() {
return theInstance;
}
}
you could do
public class FakeSingleton {
private static int aVar = 10;
public static void aMethod() {
System.out.println(aVar);
}
}
and have exactly the same functionality (instead of Singleton.getInstance().aMethod() you would write FakeSingleton.aMethod()).
Using the singleton pattern can be advantageous if you want lazy initialization, so that the singleton is only initialized when it is first needed, as follows:
public class Singleton {
private static Singleton theInstance = null;
private int aVar = 10;
public void aMethod() {
System.out.println(aVar);
}
public static Singleton getInstance() {
if (theInstance == null) {
theInstance = new Singleton();
}
return theInstance;
}
}
(Note that the above is not thread-safe, in multithreaded code you will need to add synchronization.)
I have a Singleton class to save the state of an application's module.
This class simply have a lot of class variables with setters and getters :
public class ModuleState{
private static ModuleState instance;
private A a;
private B b;
private C c;
..
..
..
..
private ModuleState (){}
public ModuleState getInstance(){
if(instance==null)
instance=new ModuleState();
return instance;
}
}
At a precise moment of the application lifecycle, i have the need to CLEAR the module's state. What i do now is to reset ALL the variables in ModuleState by a clearAll() method like this:
public void clearAll(){
a=null;
b=null;
c=null;
..
..
}
My question is the following : there is a cleaner method to do this reset? Possibly clearing the singleton instance itself, without resetting every class variable?
The problem with this approach is that i may have the need to add a new class variable to the ModuleState. In this case i must remember to add a line in the clearAll() method to reset the new variable.
What about ...
public static volatile ModuleState instance = null;
public static void reset() {
instance = new ModuleState();
}
p.s.: as per discussion below: in a multithreaded environment it's very important to synchronize the access on the instance because the JVM is allowed to cache its value. You can use volatile as shown above. Thanks to all!
Cheers!
no, this approach is perfectly acceptable. you are of course synchronizing access to these state objects in some way, right? otherwise you risk someone seeing a half-cleared config object.
another thing you could do to future-proof yourself against any extra state added in the future is store all of your state in a HashMap, for example, instead of individual fields. this way, clear()ing the hashmap ensures that all state is wiped and adding any extra state in the future becomes safer
You need to maintain the same object instance, in order to comply with the Singleton pattern, so your approach makes sense: altering the members.
However, if you wanted to clean it up a little bit, why not just have an internal list, like:
ArrayList<Object> members = new ArrayList<Object>();
// If it actually is Object, there's no need to paramaterize.
// If you want, you can actually make the members implement a common interface,
// and parameterize the ArrayList to that.
Another Option would be to have a HashMap, that binds the key word to the member.
HashMap<String,Object> members = new HashMap<String,Object>();
// Again, same parameterization rules apply.
For an ArrayList or a HashMap, the clearAll method might look like this:
public class ModuleState()
{
public void clearAll()
{
members.clear();
}
}
This method won't need to change.
May be this can help you:
public class SingletonBean {
private static SingletonBean instance = new SingletonBean();
private static Object privateMutex = new Object();
private SingletonBean() {
//to prevent instantiation
}
public class ObjectsContainer {
private Object A;
private Object B;
private Object C;
public Object getA() {
return A;
}
public void setA(Object a) {
A = a;
}
public Object getB() {
return B;
}
public void setB(Object b) {
B = b;
}
public Object getC() {
return C;
}
public void setC(Object c) {
C = c;
}
}
private ObjectsContainer objectsContainer;
private void resetObjectsContainer() {
objectsContainer = new ObjectsContainer();
}
public static SingletonBean getInstance() {
return SingletonBean.instance;
}
public static void clearAll() {
synchronized (privateMutex) {
SingletonBean.getInstance().resetObjectsContainer();
}
}
public static ObjectsContainer getObjectsContainer() {
synchronized (privateMutex) {
return instance.objectsContainer;
}
}
}
public class SomeClass {
public void someMethod() {
SingletonBean.getObjectsContainer().getA();
}
}
Make an inner class to hold the fields, then replace that instance when you want to reset. The write to the field would make the change to all three fields essentially atomic.
public class ModuleState {
private static volatile ModuleState instance;
private static class Values {
A a;
B b;
C c;
}
private volatile Values values = new Values()(
private ModuleState (){}
public ModuleState getInstance(){
if (instance==null) {
synchronized (ModuleState.class) {
if (instance==null) {
instance = new ModuleState();
}
}
}
return instance;
}
public synchronized A getA() {
return values.a;
}
public synchronized void reset() {
values = new Values();
}
By the way, your null checking initialization code was not threadsafe. I fixed that too.
Note that to make this work, you must make the reference to values volatile and synchronize all access to it, otherwise (due to the java memory model) other threads than the one that calls reset() may see the old reference.
public class GameManager {
private static GameManager INSTANCE;
private final int INITIAL_SCORE = 0;
private int mCurrentScore;
GameManager(){
}
public static GameManager getInstance(){
if(INSTANCE == null){
INSTANCE = new GameManager();
}
return INSTANCE;
}
public int getCurrentScore(){
return mCurrentScore;
}
public void incrementScore(int pIncrementBy){
mCurrentScore += pIncrementBy;
}
public void resetGame(){
mCurrentScore = GameManager.INITIAL_SCORE;
}
}
I run the above code in eclipse.
I'd like to know why eclipse told me "Cannot make a static reference to the non-static field GameManager.INITIAL_SCORE" when assigning the value of GameManager.INITIAL_SCORE to that of mCurrentScore. mCurrentScore is not static, is it? If mCurrentScore is not static, why should I declare INITIAL_SCORE as static?
When you prefix a variable with a class name you are telling Java the variable is static. Since the variable is not static it is giving you an error. The code should read:
public void resetGame(){
mCurrentScore = INITIAL_SCORE;
}
private final int INITIAL_SCORE = 0;
is not static field, it is instance field (which is same like mCurrentScore). You need to just return INITIAL_SCORE;
You can't access it is using Class name.
Can anyone please tell me whether this is a singleton class or not?
public class Final_output{
Cafe_factory obj=null;
private Final_output()
{
obj = new Cafe_factory();
obj.getOrder("French Fries");
obj.getOrder("Biryani");
obj.getOrder("Ice-cream");
}
public static void main(String args[])
{
new Final_output();
}
}
Cafe_factory is another class in the same package.
This is not a Singleton.
Singleton for Example is:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
Not, it's not. Because you can't create instances of this class outside of it (at least one instance should exist). For the other hand - you can create as many instances inside main as you wish (so it's not singleton either).
Here is an example of Singleton:
public class MySingleton{
private MySingleton(){}
private static InstanceHolder{
private static final MySingleton instance = new MySingleton();
}
public static MySingleton getInstance(){
return InstanceHolder.instance;
}
}
Its not.
A singleton has as objective to limit to 1 the number of instances of the same class that can be created, and provide static methods to retrieve this instance.
This is typically done via a private constructor and static methods to retrieve this unique instance. Here neither Final_output nor Cafe_factory respect this contract so none of them use the singleton pattern.
Since you could create n amount of new Cafe_Factory objects in your code also outside the Final_output class, no it is not a singleton. A singleton is never created with the new keyword. Instead, you fetch an instance of it via a static method.
this :
public class Final_output{
private static Cafe_factory obj = null;
private Final_output()
{
obj = getCafeInstance();
}
public static getCafeInstance(){
if(null == obj){
obj = new Cafe_factory();
obj.getOrder("French Fries");
obj.getOrder("Biryani");
obj.getOrder("Ice-cream");
}else{
return obj;
}
}
}
NO This is not a singleTon
public class Final_output{
private static Final_output ourInstance = new Final_output();
Cafe_factory obj=null;
private Final_output() {
obj = new Cafe_factory();
obj.getOrder("French Fries");
obj.getOrder("Biryani");
obj.getOrder("Ice-cream");
}
public Final_output getINstance(){
return ourInstance;
}
}