-1

To make a singleton class that is implemented using either of the previous approaches serializable (Chapter 11), it is not sufficient merely to add imple- ments Serializable to its declaration. To maintain the singleton guarantee, you have to declare all instance fields transient and provide a readResolve method (Item 77). Otherwise, each time a serialized instance is deserialized, a new instance will be created

Which leads to my question: why declare all instance fields transient ? i think readResolve is enough! my question is :why the author said we shuold declare all instance fields transient in singletons

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();
    }

}

Output is:

    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
user207421
  • 305,947
  • 44
  • 307
  • 483
  • why declare all instance fields transient ? i think readResolve is enough! – user3003728 May 03 '15 at 08:42
  • How would the instance be saved in the following case: load jvm, write class to file, unload jvm, load jvm, reload class from file? – engineercoding May 03 '15 at 09:01
  • my question is :why the author said we shuold declare all instance fields transient in singletons – user3003728 May 03 '15 at 09:16
  • Don't use quote formatting for text that isn't quoted, and ***do*** use it for text that ***is*** quoted. Your question was entirly incomprehensible because of that abuse of the formatting facilities provided. And when you quote something, provide a citation. – user207421 May 03 '15 at 09:50

3 Answers3

0

I don't think any issue will highlight if you use it in a single JVM (the class will hold the reference for the static singleton instance, no matter how you serialize it). Perhaps restarting after the serialization and reading the file would help, but I would think that class loading should happen before the deserialization.

It also has a performance consideration. If you don't need to serialize the values of the fields, because they are the same for a singleton, why would you serialize it, then e.g. send it over the network, then do readResolve just to ignore the values you received?

molnargab
  • 162
  • 7
0

(Chapter 11)

Chapter 11 of what?

To maintain the singleton guarantee, you have to declare all instance fields transient

No you don't. Making the instance variables transient is not required to provide the singleton guarantee. Providing a readResolve() method is sufficient.

my question is :why the author said we shuold declare all instance fields transient in singletons

What author? Author of what? Where did he say that? What were his exact words? What is your question?

Possibly he suggested that as a performance improvement, as serializing data that isn't going to be used is just a waste of time and space.

user207421
  • 305,947
  • 44
  • 307
  • 483
-1

If you mark an instance variable as transient, you're telling the JVM to skip (ignore) this variable when you attempt to serialize the object containing it. Serialization is one of the coolest features of Java; it lets you save (sometimes called "flatten") an object by writing its state (in other words, the value of its instance variables) to a special type of I/O stream. With serialization you can save an object to a file, or even ship it over a wire for reinflating (deserializing) at the other end, in another JVM.

Mohan Raj
  • 1,104
  • 9
  • 17