为什么在单例中声明所有实例字段是瞬态的?

时间:2015-05-03 08:41:10

标签: java serialization singleton effective-java

  

创建一个使用前一个实现的单例类   接近可序列化(第11章),仅仅添加实现是不够的   可以序列化为其声明。为了保持单身保障,你   必须声明所有实例字段瞬态并提供readResolve方法   (第77项)。否则,每次序列化实例反序列化时,都是新的   将创建实例

这引出了我的问题:为什么要声明所有实例字段是暂时的?我认为readResolve就足够了! 我的问题是:为什么作者说我们shuold声明所有实例字段在单例中是瞬态的

package com.effective.test;

import java.io.Serializable;

public class NormalBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private  transient  int id;

    /**
     * no matter declare transient or not...nothing is different!why author say that??
     */
    private/* transient */String name;

    private NormalBean(int id, String name) {
        this.id = id;
        this.name = name;
    }

    private static final NormalBean INSTANCE = new NormalBean(12345,"jack");

    public static NormalBean getInstance() {
        return INSTANCE;
    }

    /*
     * The readResolve method is called when ObjectInputStream has read an
     * object from the stream and is preparing to return it to the caller.
     * ObjectInputStream checks whether the class of the object defines the
     * readResolve method. If the method is defined, the readResolve method is
     * called to allow the object in the stream to designate the object to be
     * returned.
     * 
     * And in Singleton case we are returning the same instance that was created
     * while classloading and no new instances are returned. So singletonness is
     * maintained.
     */
    private Object readResolve() {
        return INSTANCE;
    }

    @Override
    public String toString() {
        return "NormalBean [id=" + id + ", name=" + name + ", getClass()=" + getClass() + ", hashCode()=" + hashCode()
                + "]";
    }
}

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class TestTransientPlusReadResolve {
      NormalBean bean=NormalBean.getInstance() ;
    public   void writeAndRead() throws IOException {
        ObjectOutputStream outStream = new ObjectOutputStream(new FileOutputStream("writeAndRead.txt"));
        System.out.println("this is the one "+bean );

        outStream.writeObject(bean);
        outStream.close();
        try {
            Thread.sleep(500l);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("writeAndRead.txt"));

        try {
            NormalBean backBean = (NormalBean) inputStream.readObject();
            System.out.println("this is the one "+backBean );

            System.out.println("still the One?"+(backBean==bean));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            inputStream.close();
        }
    }

    public static void main(String[] args) throws IOException {
      new TestTransientPlusReadResolve().writeAndRead();
    }

}

输出是:

    this is the one NormalBean [id=12345, name=jack, getClass()=class com.effective.test.NormalBean, hashCode()=366712642]

    this is the one NormalBean [id=12345, name=jack, getClass()=class com.effective.test.NormalBean, hashCode()=366712642]

    still the One?true

0 个答案:

没有答案