package com.linruby.singleton;
import java.io.Serializable;
public class SingletonObject implements Serializable {
private static final SingletonObject instance = new SingletonObject();
private String name = "linruby12";
private int age = 37;
private SingletonObject() {
}
public static SingletonObject getInstance() {
return instance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private Object readResolve() {
return SingletonObject.getInstance();
}
}
package com.linruby.singleton;
import java.io.*;
import static java.lang.System.out;
import static java.lang.System.setOut;
public class ClinetMain {
public static void main(String[] args) {
SingletonObject instance = SingletonObject.getInstance();
FileOutputStream fout = null;
ObjectOutputStream outObj = null;
FileInputStream fin=null;
ObjectInputStream inObj = null;
try {
fout = new FileOutputStream("d:/linruby12.obj");
outObj = new ObjectOutputStream(fout);
outObj.writeObject(instance);
outObj.flush();
fin = new FileInputStream("d:/linruby12.obj");
inObj = new ObjectInputStream(fin);
SingletonObject instance2 = (SingletonObject)inObj.readObject();
System.out.println(instance);
System.out.println(instance2);
System.out.println(instance2.getName());
System.out.println(instance2.getAge());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fout != null) {
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outObj != null) {
try {
outObj.close();
} catch (IOException e) {
e.printStackTrace();
}
}
.....
}
}
}
结果:
com.linruby.singleton.SingletonObject@6d6f6e28
com.linruby.singleton.SingletonObject@6d6f6e28
linruby12
37
那么这个readResolve()方法是从哪来的,为什么加上之后就能返回同一实例了呢?
找到ObjectInputStream类的
/**
* Reads and returns "ordinary" (i.e., not a String, Class,
* ObjectStreamClass, array, or enum constant) object, or null if object's
* class is unresolvable (in which case a ClassNotFoundException will be
* associated with object's handle). Sets passHandle to object's assigned
* handle.
*/
private Object readOrdinaryObject(boolean unshared)
throws IOException
{
if (bin.readByte() != TC_OBJECT) {
throw new InternalError();
}
ObjectStreamClass desc = readClassDesc(false);
desc.checkDeserialize();
Class<?> cl = desc.forClass();
if (cl == String.class || cl == Class.class
|| cl == ObjectStreamClass.class) {
throw new InvalidClassException("invalid class descriptor");
}
Object obj;
try {
obj = desc.isInstantiable() ? desc.newInstance() : null;
} catch (Exception ex) {
throw (IOException) new InvalidClassException(
desc.forClass().getName(),
"unable to create instance").initCause(ex);
}
passHandle = handles.assign(unshared ? unsharedMarker : obj);
ClassNotFoundException resolveEx = desc.getResolveException();
if (resolveEx != null) {
handles.markException(passHandle, resolveEx);
}
if (desc.isExternalizable()) {
readExternalData((Externalizable) obj, desc);
} else {
readSerialData(obj, desc);
}
handles.finish(passHandle);
// 这个位置调用readResolve方法
if (obj != null &&
handles.lookupException(passHandle) == null &&
desc.hasReadResolveMethod())
{
Object rep = desc.invokeReadResolve(obj);
if (unshared && rep.getClass().isArray()) {
rep = cloneArray(rep);
}
if (rep != obj) {
handles.setObject(passHandle, obj = rep);
}
}
return obj;
}