单例实现的一种方式:私有构造器,公有静态工厂方法
public class Singleton2 {
private static final Singleton2 INSTANCE = new Singleton2(); // 私有静态final域
/*
* 私有构造器
*/
private Singleton2() {
}
/*
* 公有静态工厂方法
*/
public static Singleton2 getInstance() {
return INSTANCE;
}
}
这段话是effective java中的描述,我不理解的是为什么仅仅加上implements Serializable不行呢,反序列化一个序列化的实例时会创建一个新的实例?
--
补充问题:
关于这种单例模式有一种评论如下:这种方式基于classloder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 但是也不能确定有
其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。
这里的其他方式还可以是什么?
1 Why just adding implements serializable doesn’t work
The basis of this method of building a singleton pattern is encapsulation. How to implement a singleton? Since the constructor has become private, it cannot be constructed externally and can only be obtained through Singleton2.getInstance(). This achieves a single column, but is this the case during serialization? How does the sequence object know to call getInstance() to obtain the object? Let’s take a look at the implementation of Java’s underlying serialization and open the ObjectStreamClass class in the JDK (this class is responsible for serializing class objects)
Following the trace further, it can be clearly seen that it uses reflection to serialize. It uses reflection instead of calling getinstance(). Of course, the singleton will fail
2 A new instance is created every time a serialized instance is deserialized
Since reflection is also used during deserialization, of course each object will create a new instance
Let me add that when deserializing here, a new instance will be generated because the access permission restrictions in Java can be bypassed in reflection.
http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible(boolean)
corresponds to the java source code, jdk1.7.0.21, ObjectStreamClass.java:
In this way, during deserialization, you can directly call singleton's private constructor to generate a new object instance.