package p1;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SerializationCheck {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
SingletonCompanyCEO s1 = SingletonCompanyCEO.getSingleObject();
SingletonCompanyCEO s2 = SingletonCompanyCEO.getSingleObject();
System.out.println("s1==s2:"+(s1==s2));
ObjectOutputStream obs = new ObjectOutputStream(new FileOutputStream("file.txt"));
obs.writeObject(s1);
//first read from file
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.txt"));
SingletonCompanyCEO ceo = (SingletonCompanyCEO)ois.readObject();
//second read from file
ois = new ObjectInputStream(new FileInputStream("file.txt"));
SingletonCompanyCEO ceo1 = (SingletonCompanyCEO)ois.readObject();
System.out.println("ceo==ceo1:"+(ceo==ceo1)+" (read from file ie. de-serialized )");
System.out.println(ceo1);
}
}
class SingletonCompanyCEO implements Serializable
{
public void setName(String name){
this.name = name;
}
public Object readResolve() throws ObjectStreamException {
return singleObject;
}
private static final long serialVersionUID = 1L;
private transient int age = 55; // age should set to zero by default as age is transient. But it is not happening, any reason?
private String name ="Amit";
float salary = 0f;
private static SingletonCompanyCEO singleObject;
private SingletonCompanyCEO()
{
if(singleObject!=null)
{
throw new IllegalStateException();
}
}
public static SingletonCompanyCEO getSingleObject()
{
if(singleObject==null)
{
singleObject = new SingletonCompanyCEO();
}
return singleObject;
}
public String toString()
{
return name+" is CEO of the company and his age is "+
age+"(here 'age' is transient variable and did not set to zero while serialization)";
}
}
在eclipse编辑器中复制并粘贴此代码。
在序列化时,默认情况下'age'transient
变量未设置为零的原因是什么?
序列化表示序列化时瞬态和静态变量设置为零(或默认值)。
在反序列化后,我得到的是age = 55
而不是age = 0
。
在JLS中必须有这样的理由。它是什么?
答案 0 :(得分:1)
您正在使用SingletonCompanyCEO
方法提供静态getSingleObject
对象。因此,您SingletonCompanyCEO
的以下参考变量,即s1
,s2
共享相同的SingletonCompanyCEO
对象。对于此唯一对象,您具有以下字段值:
age = 55;
name ="Amit";
salary = 0f;
但是您还在readResolve
类中覆盖了SingletonCompanyCEO
方法,其中您返回s1
和s2
引用的同一对象。因此,在对类JVM进行反序列化时,变量ceo
和ceo1
将引用s1
和s2
引用的同一对象。所以基本上你在序列化之前和反序列化之后都有一个SingletonCompanyCEO
类的对象。这就是age
打印为55
的原因。
<强>更新强>
以下是在代码中删除readResolve
后代码中涉及的步骤:
readResolve
中查找SingletonCompanyCEO
方法。
JVM找不到readResolve
并将新对象返回到反序列化返回的ceo
。readResolve
中查找SingletonCompanyCEO
方法。
JVM找不到readResolve
并将新对象返回到反序列化返回的ceo1
。因此,在两次反序列化后,你有两个新的对象
SingletonCompanyCEO
。
=&GT; ceo == ceo1返回false 注意:在新创建的对象中,age
的值将为JLS指定的0。
<强> UPDATE2 强>
如果您对writeobject
部分代码发表评论并使用现有文件(file.txt
)反序列化该类,则在反序列化时会执行以下步骤:
readResolve()
类中查找SingletonCompanyCEO
方法。 JVM仅将该对象返回给由类中定义的readResolve()
方法返回的变量。readResolve()
方法。在readResolve()
方法中,您暂时返回singleObject
null
,因为方法getSingleObject()
仍未调用。并且为了您的信息,在反序列化时也不会调用类的构造函数,否则它会像在构造函数中那样抛出IllegalstateException
。readResolve()
正在返回null
因此JVM也返回null
。结果ceo1
和ceo2
都是null
。答案 1 :(得分:1)
每次反序列化SingletonCompanyCEO对象时,都会丢弃从ObjectInputStream获取的所有信息,而是由于readResolve
方法而返回单个对象。 singleObject本身就是一个使用构造函数创建的实例,而不是反序列化,因此它的年龄为55岁。
答案 2 :(得分:0)
private transient int age = 55;
在声明中定义值时,这将优先。