我已经制作了一个序列化的类,就像这样
`
class Example implements Serializable
{
transient byte i=2;
transient byte j=3;
Example(){System.out.println("value of i:"+i+",j:"+j);}
}
`
当我对该类进行反序列化时,即
class SerialClass
{
public static void main(String []r)//throws IOException
{
try{
System.out.println("Serialization");
Example e=new Example();
FileOutputStream out=new FileOutputStream("hyxa_code.txt");
/*File f=new File("copt.txt");
f.createNewFile();*/
ObjectOutputStream oo=new ObjectOutputStream(out);
oo.writeObject(e);
oo.close();}catch(IOException e){}
try{
System.out.println("Deserialization");
Example ee=new Example();
FileInputStream in=new FileInputStream("hyxa_code.txt");
ObjectInputStream o=new ObjectInputStream(in);
ee=(Example)o.readObject();
System.out.println("The vlaue of i,j:"+ee.i+" "+ee.j);
}catch(IOException e)
{}
catch(ClassNotFoundException e){}
}
}
输出是这样的:
Serialization
value of i:2,j:3
Deserialization
value of i:2,j:3
The vlaue of i,j:0 0
但正如我所听到的,反序列化不会初始化构造函数, 这里正在发生,为什么??? 另外,为什么两个变量的值都在初始化时出现
答案 0 :(得分:4)
将变量标记为瞬态会使它们不被序列化。删除变量声明的瞬态部分,它将起作用。
对于未在反序列化过程中调用的构造函数,您是正确的。对象的状态直接从流加载,不调用构造函数。
有关详细信息,请参阅http://www.rockstarprogrammer.org/post/2006/jul/29/more_you_want_know_about_java_serialization/。当反序列化发生时,readObject方法可用于初始化瞬态变量。
答案 1 :(得分:4)
您显式调用构造函数两次 - 一次序列化,然后在反序列化时调用一次:
Example ee=new Example();
FileInputStream in=new FileInputStream("hyxa_code.txt");
ObjectInputStream o=new ObjectInputStream(in);
ee=(Example)o.readObject();
System.out.println("The vlaue of i,j:"+ee.i+" "+ee.j);
你忽略了你创造的价值,所以代码实际上是这样的:
FileInputStream in=new FileInputStream("hyxa_code.txt");
ObjectInputStream o=new ObjectInputStream(in);
Example ee=(Example)o.readObject();
System.out.println("The vlaue of i,j:"+ee.i+" "+ee.j);
不同之处在于,这次你不会不必要地调用构造函数。
这就解释了为什么你会两次看到“i:2,j:3”的值。反序列化对象的值为0的原因是因为您已将变量声明为transient
,如其他答案中所述。
答案 2 :(得分:2)
瞬态变量不能被序列化,因此变量的值变为0。
这里有一个例子:http://javatechnologyhelper.blogspot.com/2014/04/java-serialization.html
另外,您可以查看:http://en.wikibooks.org/wiki/Java_Programming/Keywords/transient。
transient是一个Java关键字,它标记成员变量不是 在持久化为字节流时序列化。当一个物体是 通过网络传输,该对象需要被序列化'。 序列化将对象状态转换为串行字节。那些字节 通过网络发送,并从那些重新创建对象 字节。由java transient关键字标记的成员变量不是 转移,他们故意丢失。
答案 3 :(得分:1)
由于i和j都被标记为瞬态,因此它们不会被序列化。因此,当您反序列化时,它们将具有byte的默认值,即0。