单例类问题

有人在iteye上提出了单例类的问题,下面是一个精彩的回答。

 

写一个单例应该需要考虑一个重要问题,对象是怎么创建的:
1
、通过构造函数创建
2
、通过反射创建
3
、通过反序列化创建
4
、通过clone创建

提供的解决方案如下:

1
、禁止外部调用构造函数设置 private

2
、禁止反射设置构造函数创建accessable,调用构造函数,可以再构造函数内判断是否已经创建过对象

3
、禁止反序列化创建对象,需要重写readResolve方法

4
、禁止clone,其实也不算禁止吧,重新clone,返回你的引用就OK

你看看你的单例有没有处理这几种情况,关于synchronized,个人还是觉得需要使用,考虑到线程安全问题

 

单例类的序列化

一个单例类要想序列化,仅让其实现serializable 是不够的,还需要写

  private Object readResolve() throws ObjectStreamException {

  return instance;

  }//这个方法可以在反序列化之后内存中不会有该类的多个实例

如下,进行序列化/反序列化

   public static void main(String[] args) throws Exception {
        
// 序列化
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(
                new FileOutputStream("c:\\Singleton.clazz"));
        Singleton singleton = Singleton.uniqueInstance;
        objectOutputStream.writeObject(singleton);
        objectOutputStream.close();
      
 // 反序列化
        ObjectInputStream objectInputStream = new ObjectInputStream(
                new FileInputStream("c:\\Singleton.clazz"));
        Singleton singleton2 = (Singleton) objectInputStream.readObject();
        objectInputStream.close();
      
 // 比较是否原来的实例
        System.out.println(singleton == singleton2);
    }//
如果不加readResolved方法,两个结果不相等,加上,则相等。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值