枚举实现单例模式
java
it书童
2020-12-27 08:11:09
0赞
0踩
94阅读
0评论
枚举可能是实现单例的最佳方式
public enum EnumInstance {
INSTANCE;
private Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static EnumInstance getInstance() {
return INSTANCE;
}
}
public class Test {
public static void main(String[] args) throws Exception {
EnumInstance instance = EnumInstance.getInstance();
instance.setData(new Object());
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file"));
oos.writeObject(instance);
File file = new File("singleton_file");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
EnumInstance newInstance = (EnumInstance) ois.readObject();
System.out.println(instance.getData());
System.out.println(newInstance.getData());
System.out.println(instance.getData() == newInstance.getData());
}
}
java.lang.Object@7291c18f
java.lang.Object@7291c18f
true
以上说明枚举类扛过了序列化破坏
这时,反射蠢蠢欲动,要来试下
public static void main(String[] args) throws Exception {
Class<EnumInstance> objectClass = EnumInstance.class;
Constructor<EnumInstance> constructor = objectClass.getDeclaredConstructor();
// 通过反射,将权限打开
constructor.setAccessible(true);
}
直接报异常 NoSuchMethodException
,无法获取枚举类的无参构造器
反射踩到铁钉子了,由此可见,枚举类天然地不惧序列化以及反射破坏
查看 Enum 源码,发现其只有一个构造器
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
反射贼心不死,继续在犯罪的边缘试探,直接拿带参构造器来处理
public static void main(String[] args) throws Exception {
Class<EnumInstance> objectClass = EnumInstance.class;
Constructor<EnumInstance> constructor = objectClass.getDeclaredConstructor(String.class, int.class);
// 通过反射,将权限打开
constructor.setAccessible(true);
EnumInstance enumInstance = constructor.newInstance("Geely", 66);
}
执行,继续报错:
这下就真的 GG 了,你再牛,也牛不过 jdk 的规定吧
- 上一篇: 单例模式如何应对反射攻击
- 下一篇: 将单例对象存入容器

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/1014
精品付费
个人开发者通过payjs接入微信支付
2583
0
这一次,真正掌握composer
1509
0
相关推荐
java ServletContext 对象详解
177
0
java 入门 jvm jre jdk
177
0
Java Date 类介绍
158
0
Java 服务调用方式
187
0
什么是Hystrix
180
0
SpringBoot 整合 Junit
101
0
java使用ForkJoinPool利用多CPU
126
0
饿汉式创建单例模式
97
0
atomic包-原子类
59
0
筛选购物车商品-引出函数式接口妙用
46
0