对象序列化与反序列化
序列化,并不是JAVA独有的。因此,在这里我用比较通俗的话说了。序列化就是把一个对象转换成有规则的二进制流。而反序列化就是把有规则的二进制数据重整成一个对象。其好处不难看见:1.可以把一个对象保存在一个文件里。例如,下载软件。当您关闭了软件,下次再打开下载,可以读回上次下载的相关信息。呵呵...好处在乎您怎样运用罢了。2.可以把一个对象通过网络流发送给远程机器。其实这样可以用RMI,或者自己制造些标记,发到远程机器时,将其解释。本人觉得那样还好。不过如果向远程机器发送对象,相对于自己制造标记组合在一起发送,发送对象其软件偶合性会降低。(本人见解。)UDP发送对象其原理也是一样的。现在看看代码:
import java.io.*;
class A implements java.io.Serializable{
//静态值不序列化.
static long someValue = 1;
//序列化
int foo = 10;
//Transien 属性不序列化
transient String bar = "Hello World";
//如果baz指向A B实例,那么其对象也序列化
B baz;
}
class B extends A{
//不序列化
transient long lastRead;
//序列化
int serializationCount = 0;
//自行处理反序列方法,如果没有其方法,系统会自动取采默认的方法进行反序列化。(通常自行处理,是为了提高处理反序列的速度。)
private void readObject(ObjectInputStream in){
try{
//使用默人的反序列方法。
in.defaultReadObject();
}catch(IOException ex){
ex.printStackTrace();
}catch(ClassNotFoundException ex){
ex.printStackTrace();
}
//反序列化后统计。(大家思考一下吧~~~这里做个统计,我是有什么意思。)
serializationCount ++;
//设置其transient的值。
lastRead = System.currentTimeMillis();
}
}
public class SerializationTest{
public static void main(String[] args){
try{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
//创建对象并改变对象的一些值.
A obj = new A();
obj.foo = 11;
obj.bar = "GoodBye World...";
obj.baz = new B();
obj.baz.lastRead = -1;
//序列化对象
out.writeObject(obj);
//创建一个流用来反序列对象
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
//反序列的对象
obj = (A)in.readObject();
System.out.println(obj.foo); //print 11;
System.out.println(obj.bar); //print null;
System.out.println(obj.baz.serializationCount);//print 1;
}catch(IOException ex){
ex.printStackTrace();
}catch(ClassNotFoundException ex){
ex.printStackTrace();
}
}
}
现在作些解释吧~~ 以上序列化器和反序列化器是同一个对象,而惟一的中间媒体是一个字节数组。readObject在ObjectInputStream.readObject被调用时调用。它所做的第一件事是调用缺省的反序列化过程,该过程把SerializationCount恢复到实例刚被序列化时的数组。该值随后会递增。随后,可以随过查看该值看一下这个特定的对象被序列化的反序列的次数。注意:如果使用与输入相同的字节流进行反序列化运算,就会有两个相同的对象。
CAnca 的陋室
2007.3.18