`
erhuzi
  • 浏览: 6653 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

单例模式及其序列化/反序列化

阅读更多
        为了使一个单例类变成可串行化的,仅仅在声明中添加“implements Serializable”是不够的。因为一个串行化的对象在每次返串行化的时候,都会创建一个新的对象,而不仅仅是一个对原有对象的引用。为了防止这种情况,可以在单例类中加入readResolve 方法。
        下面我们先简要地回顾下对象的序列化. 一般来说, 一个类实现了 Serializable接口, 我们就可以把它往内存地写再从内存里读出而"组装"成一个跟原来一模一样的对象. 不过当序列化遇到单例时,这里边就有了个问题: 从内存读出而组装的对象破坏了单例的规则. 单例是要求一个JVM中只有一个类对象的, 而现在通过反序列化,一个新的对象克隆了出来.
如下例所示:     
public final class MySingleton implements Serializable {  
     private MySingleton() { }  
     private static final MySingleton INSTANCE = new MySingleton();  
     public static MySingleton getInstance() { return INSTANCE; }  
}  

当把 MySingleton对象(通过getInstance方法获得的那个单例对象)序列化后再从内存中读出时, 就有一个全新但跟原来一样的MySingleton对象存在了. 那怎么来维护单例模式呢?这就要用到readResolve方法了.如下所示:
public final class MySingleton implements Serializable{  
    private MySingleton() { }  
    private static final MySingleton INSTANCE = new MySingleton();  
    public static MySingleton getInstance() { return INSTANCE; }  
    private Object readResolve() throws ObjectStreamException {  
       // instead of the object we're on,  
       // return the class variable INSTANCE  
      return INSTANCE;  
   }  
}  

这样当JVM从内存中反序列化地"组装"一个新对象时,就会自动调用这个 readResolve方法来返回我们指定好的对象了, 单例规则也就得到了保证 。
分享到:
评论

相关推荐

    设计模式之单例模式(结合工厂模式)

    静态内部类单例利用Java类加载机制保证了线程安全,而枚举单例则是Java中实现单例的最佳方式,因为它天然支持序列化且防止反射攻击。 在代码实现上,我们可以创建一个名为SingletonFactory的工厂类,其中包含一个...

    单例模式,single

    - **序列化的影响**:如果单例类实现了 `Serializable` 接口,那么通过序列化和反序列化可能会产生新的实例,这同样会破坏单例模式。 针对上述问题,可以采取以下几种策略: 1. **线程安全的单例模式**:可以通过...

    php单例模式实例

    4. 防止序列化和反序列化:如果允许对象被序列化和反序列化,可能会导致单例模式失效,因此我们需要封锁`__wakeup()`和`__sleep()`方法。 ```php class Singleton { // ... private function __wakeup() { ...

    单例模式介绍

    下面我们将详细介绍六种常见的单例模式,并探讨在Android环境下如何应对反序列化安全问题。 1. 饿汉式单例(Static Singleton) 这是最简单的单例实现方式,通过静态常量来存储唯一实例,保证在类加载时就完成初始...

    单例模式源代码

    以上就是Java中实现单例模式的各种方法及其特点,每种方式都有其适用场景,开发者应根据实际需求选择合适的实现方式。了解并掌握这些单例模式的实现方式,对于后续学习其他设计模式以及提高代码质量都是非常有帮助的...

    单例模式代码和文档

    7. 枚举单例:简洁且能防止反序列化重新创建新的实例。 ```java public enum Singleton { INSTANCE; public void whateverMethod() {} } ``` 三、单例模式的优点 1. 单例模式可以保证系统内存中该类只存在一个...

    序列化类的作用Serializable

    `readResolve()`则是在反序列化时用来替换读取的对象,通常用于处理类版本控制或者单例模式。 为了确保序列化和反序列化的兼容性,Java引入了一个名为`serialVersionUID`的版本号。这是一个长期(long)类型的静态...

    单例模式的Java示例代码

    以下是对单例模式及其Java实现的详细解释。 ### 单例模式的核心思想 1. **唯一性**:确保类只有一个实例。 2. **全局访问点**:提供一个全局访问点,让所有需要使用该实例的代码都能方便地获取到它。 3. **延迟...

    Java 序列化的秘密(高清PDF中文版)

    这是因为反序列化会创建一个新的实例,即使原类实现了单例模式。为了解决这个问题,可以在类中添加一个`readResolve()`方法,该方法会在反序列化过程中被调用,用于返回正确的单例实例。 #### 同引用实例化问题 在...

    二十三种设计模式Java版之单例模式

    理解并掌握单例模式的实现方式及其优缺点对于编写高效、可维护的Java代码至关重要。在实际应用中,应根据项目需求选择合适的单例实现方式。例如,如果对性能要求较高且不需要延迟初始化,饿汉式可能是个好选择;而...

    单例模式SingletonMode

    枚举方式不仅避免了同步问题,还能防止反序列化导致的多实例问题。 单例模式的优点包括: - 节省内存:只创建一个实例,节省系统资源。 - 全局访问点:提供一个全局访问点,方便对单例对象的操作。 - 控制实例化...

    设计模式之单例

    1. **防止反序列化创建新实例**:默认情况下,Java序列化会破坏单例,可以通过实现 `readResolve()` 方法来解决这个问题。 2. **线程安全**:确保在多线程环境下,单例的实例化过程是线程安全的。 3. **懒加载与初始...

    单例设计模式个人总结+摘录

    本文将详细介绍几种常见的单例模式实现方式及其特点。 #### 单例模式优点 1. **资源节约**:通过单例模式,可以确保系统中某个类只有一个实例,从而减少资源消耗。 2. **控制共享资源的访问**:在多线程环境下,...

    2 单例模式-课程内容.rar

    6. 枚举方式:这是Java特有的实现方式,既简单又线程安全,还能防止反序列化重新创建新实例。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 以上就是单例模式的常见实现...

    教会你如何用好单例及单例的定义

    - **枚举**:自Java 5起,使用枚举来实现单例模式被认为是一种既简单又高效的方式,因为枚举天然具备线程安全性和序列化机制。 #### 六、总结 单例模式在实际项目中有着广泛的应用,特别是在需要控制资源消耗、...

    android单例

    下面我们将深入探讨Android中的单例模式及其实现方式。 **一、单例模式的概念** 单例模式是一种创建型设计模式,它的核心思想是限制类的实例化,只允许存在一个全局实例。这有助于减少系统内存开销,同时避免了多...

    单例模式-----<ant求职记之设计模式>

    在《ant求职记之设计模式》这篇博文中,作者可能通过一个生动的故事来解释了单例模式的重要性及其各种实现方式,同时可能探讨了在实际项目中如何选择合适的单例实现策略。通过学习和理解单例模式,开发者可以更好地...

    java 使用单例模式计算某一年(默认今年)一共有多少个周,以及列出每一周和其所对应的时间段(内含注释)

    通过上述代码实现了基于单例模式的日期周数计算功能,不仅能够计算出指定年份的所有周数及其具体时间范围,还能够快速获取当前日期所处的周数。这种方式在需要频繁查询或计算日期相关数据的应用场景中非常实用,同时...

    MVC总结大全

    ### MVC总结大全——深入解析Utils工具类、...以上就是关于`Utils`工具类、实体类序列化、单例模式以及`DbUtils`工具类的相关知识点总结。通过理解和掌握这些基础知识,开发者可以在实际项目开发中更加高效地解决问题。

Global site tag (gtag.js) - Google Analytics