创建单例模式一般人都知道是有懒汉模式 跟 恶汉模式,
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null) {
instance = new Singleton();
return instance;
}
return instance;
}
}
在Spring中单例在同一个容器中只有一个实例,那么Spring的单例真的是安全的吗???我们可不可以破坏它呢??
public static void main(String[] args) throws Exception{
Singleton singleton = Singleton.getInstance();
Singleton singleton1 = Singleton.getInstance();
System.out.println(singleton.hashCode());
System.out.println(singleton1.hashCode());
}
现在我们换种方式获取,,,就是利用反射
public static void main(String[] args) throws Exception{
Singleton singleton = Singleton.getInstance();
Singleton singleton1 = Singleton.getInstance();
System.out.println(singleton.hashCode());
System.out.println(singleton1.hashCode());
//利用反射获取该实例
Constructor<Singleton> declaredConstructor = Singleton.class.getDeclaredConstructor();
Singleton singleton2 = declaredConstructor.newInstance();
System.out.println(singleton2.hashCode());
}
接下来看下三个对象的hashCode的值
利用反射我们可以获取另外一个实例,所以懒汉模式或者恶汉模式下的单例我们是可以破坏的,甚至Spring的单例我们也是可以破坏的,那么有没有其它一种方式实现单例安全呢????
那就是利用枚举 ,首先我们看下反射获得对象的方法
Singleton singleton2 = declaredConstructor.newInstance();
看下它的源码
如果使用枚举的话,在你利用反射获取实例是会报错的
这是我们的枚举类
利用反射获取实例就会抛出异常
但是正常获取那么就是同一个实例