Java Serializable系列化与反系列化(二)

2014-11-24 03:19:37 · 作者: · 浏览: 1
ln("test serializable");

}

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