序列化与单例

简介:
当单例模式的类实现了系列化Serializable接口,也可以通过反序列化来使它不再单例。 
我们的单例类:
 
?
1
2
3
4
5
6
7
8
9
10
11
12
public final class Singleton implements Serializable{
 
     private static final long serialVersionUID = 1735776740157142434L;
     
     private static final Singleton instance= new Singleton();
     
     private Singleton(){}
     
     public static Singleton getInstance(){
         return instance;
     }
}

序列化和反序列化如下:  
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Singleton singleton1=Singleton.getInstance();
         
         FileOutputStream fileOut= new FileOutputStream( "D:\\singleton.txt" );
         ObjectOutputStream out= new ObjectOutputStream(fileOut);
         out.writeObject(singleton1);
         out.close();
         
         FileInputStream fileInputStream= new FileInputStream( "D:\\singleton.txt" );
         ObjectInputStream in= new ObjectInputStream(fileInputStream);
         Singleton singleton2=(Singleton)in.readObject();
         in.close();
         
         System.out.println(singleton1);
         System.out.println(singleton2);
         System.out.println(singleton1==singleton2);

先将singleton1序列化到一个文件中,然后再从该文件中读取出singleton2,结果如下:  
?
1
2
3
com.lg.design.singleton.hungry.Singleton @173e55db
com.lg.design.singleton.hungry.Singleton @4690d3c6
false

可以看到Singleton不能保证是一个单例类。但是解决方法(不能解决所有情况)为我们认为的干预序列化,使之返回我们自定义的对象,这就需要在Singleton 中添加一个readResolve方法,如下:  
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public final class Singleton implements Serializable{
 
     private static final long serialVersionUID = 1735776740157142434L;
     
     private static final Singleton instance= new Singleton();
     
     private Singleton(){}
     
     public static Singleton getInstance(){
         return instance;
     }
     
     private Object readResolve(){
         return instance;
     }
}

此时再次执行,singleton1和singleton2便是同一个对象了,如下:  
?
1
2
3
com.lg.design.singleton.hungry.Singleton @35427e6e
com.lg.design.singleton.hungry.Singleton @35427e6e
true

有关序列化的具体详细内容,请见后续文章。 
相关文章
|
6月前
|
安全 Java
Java单例---序列化破坏单例模式原理解析(二)
Java单例---序列化破坏单例模式原理解析
49 0
|
6月前
|
Java
Java单例---序列化破坏单例模式原理解析(一)
Java单例---序列化破坏单例模式原理解析
75 0
|
安全 Java
《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一2.4.4 序列化单例和类型安全的枚举
本节书摘来华章计算机《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一书中的第2章 ,第2.4.4节,[美] 凯S.霍斯特曼(Cay S. Horstmann) 著陈昊鹏 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1214 0
|
安全 设计模式
单例设计模式反射,序列化漏洞及解决方案
单例设计模式的实现方式有很多种,如饿汉式,懒汉式,双重检查锁,静态内部类,枚举等等,但是在平时的开发中,我们实现的单利模式是有一定的漏洞的,可以通过反射或者序列化以及反序列化获取不同的实例,虽然这个漏洞在系统运行的时候不会体现出来,但是在开发时也是值得注意的问题。
1338 0
|
设计模式 Java
序列化对单例的破坏
                                                                                序列化对单例的破坏 本文将通过实例+阅读Java源码的方式介绍序列化是如何破坏单例模式的,以及如何避免序列化对单例的破坏。
1315 0
|
Java
单例,枚举,反射,序列化--effectiveJava读书笔记
<h2>先看一个单例:</h2> <p></p> <pre code_snippet_id="555854" snippet_file_name="blog_20141218_1_3706" name="code" class="java">public class Singleton{ private final static Singleton INSTANCE = new S
1471 0
|
9天前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
22天前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。