栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java单例破坏以及防止

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java单例破坏以及防止

单例实现的方式有很多种,如有需要,请查设计模式——单例_程序员Forlan的博客-CSDN博客

下面我们以静态内部类为例

public class Demo{

	private Demo(){
	}

	public static Demo getInstance(){
		return Inner.demo;
	}

	private static class Inner{
		private static Demo demo = new Demo();
	}
}
反射破坏单例

原理

反射可以访问私有构造方法,通过反射拿到的构造器,再setAccessible(true),就能够实例化,每调用一次产生一个实例,从而破坏单例

实现

Demo instance = Demo.getInstance();
Constructor constructor = Demo.class.getDeclaredConstructor();
constructor.setAccessible(true);
Demo demo = constructor.newInstance();
System.out.println(instance == demo); // 结果为false

防范

private Demo(){
	if(Inner.demo != null){
		throw new RuntimeException("非法操作");
	}
}

直接抛出异常Caused by: java.lang.RuntimeException: 非法操作

序列化破坏单例

实现

// class implement Serializable,才能序列化
try(ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("G:\temp.txt"));
    ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(("G:\temp.txt")));){
    Demo instance = Demo.getInstance();
    outputStream.writeObject(Demo.getInstance());
    Demo demo = (Demo) inputStream.readObject();
    System.out.println(instance == demo); // 结果为false
} catch (Exception e){
    e.printStackTrace();
}

防范

定义readResolve方法,反序列化时则直接返回此方法指定的对象,而不需要单独再创建对象

private Object readResolve() {
	return Inner.demo;
}
最安全的方法
public enum Demo {

    INSTANCE;
}

通过源码可以发现,枚举默认就是单例的,不能进行实例化

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/859045.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号