}
public static void main(String[] args) throws Exception {
}
}
view plain
package wen.hui.test.serializable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 序列化保存的是对象的状态,静态变量属于类的状态,不会被序列化
* @author whwang
* 2011-12-1 下午10:12:06
*/
public class Test2 {
public static void main(String[] args) {
try {
// 初始时staticVar为10
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("obj"));
out.writeObject(new A());
out.close();
// 序列化后修改为100
A.staticVar = 100;
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(
"obj"));
A t = (A) oin.readObject();
oin.close();
// 再读取,通过t.staticVar打印新的值
System.err.println(t.staticVar);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
A类的静态字段staticVar初始化值为10,在Teste2的main方法中,将A类的一个实例系列化到硬盘,然后修改静态字段staticVar = 100,接着反系列化刚系列化的对象,输出”该对象的“staticVar的值。输出的是100 还是10 呢?
结果输出是100,之所以打印100 的原因在于序列化时,并不保存静态变量,这其实比较容易理解,序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。
【父类的序列化与Transient 关键字】
情境:一个子类实现了Serializable 接口,它的父类都没有实现Serializable 接口,序列化该子类对象,然后反序列化后输出父类定义的某变量的数值,该变量数值与序列化时的数值不同。
解决:要想将父类对象也序列化,就需要让父类也实现Serializable 接口。如果父类不实现的话的,就 需要有默认的无参的构造函数。在父类没有实现Serializable 接口时,虚拟机是不会序列化父对象的,而一个Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果你考虑到这种序列化的情况,在父类无参构造函数中对变量进行初始化,否则的话,父类变量值都是默认声明的值,如int 型的默认是0,string 型的默认是null。
Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如int 型的是0,对象型的是null。
view plain
package wen.hui.test.serializable;
/**
*
* @author whwang
* 2011-12-1 下午10:23:10
*/
public class B {
public int b1;
public int b2;
public B() {
this.b2 = 100;
}
}
view plain
package wen.hui.test.serializable;
import java.io.Serializable;
/**
*
* @author whwang
* 2011-12-1 下午09:49:51
*/
public class C extends B implements Serializable {
private static final long serialVersionUID = 1L;
public int c1;
public int c2;
public C() {
// 给b1,b2赋值
this.b1 = 1;
this.b2 = 2;
this.c2 = -100;
}
}
view plain
package wen.hui.test.serializable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 如果父类没有实现Serializable,那么父类不会被系列化,当反系列化子类时
* 会调用父类无参的构造方法。
* @author whwang
* 2011-12-1 下午10:23:51
*/
public class Test3 {
public static void main(String[] args) {
try {
ObjectOutputStream out = new ObjectO