您的位置:首页 > 产品设计 > UI/UE

Serializable 和 serialVersionUID

2012-10-12 16:19 405 查看
如果需要使用ObjectInputStream和ObjectOuputStream的readObject以及writeObject()方法写入和读取非Java的基础类,需要对该类进行序列化。

例如,如果需读写String,数组,枚举类型以及Java的基本数据类型,

则不需要做其他额外操作可以直接使用readObject()和writeObject()方法读取。

如果是自己创建的Class,那就不行啦,会得到一个NotSerializableException。

比如下面的代码:

import java.io.*;

public class TestObjectIO {

public static void main(String[] args) {
T t=new T();
t.i=10;
int a[] = {1,2,3};
try {
FileOutputStream fos=new FileOutputStream("d:/Java/io.dat");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(t);
oos.writeObject(a);
oos.flush();

oos.close();

FileInputStream fis=new FileInputStream("d:/Java/io.dat");
ObjectInputStream ois=new ObjectInputStream(fis);

T tread=(T)ois.readObject();
int b[] = (int [])ois.readObject();

System.out.println(tread);
System.out.println(tread.i+" "+tread.b+" "+tread.d+" "+tread.f);
System.out.println("b [] :"+b[0]+b[1]+b[2]);

//ois.fulsh();
ois.close();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}
class T implements Serializable{
public static final long serialVersionUID = 2862048673777473868L;

int i=8;
double d=1.0;
boolean b=true;
transient float f=1.8f; //transient 表示不进行序列化
public String toString(){
return "int i= "+i+"\ndouble d= "+d+"\nboolean b= "+b+"\nfloat f= "+f;
}
}


解决方法呢,就是给myClass类加上implements Serializable接口。

实现Serializable接口的没有任何额外要求,但是有一个建议就是在类中指定一个SerializableUID。

SerializableUID的用途如下:

1,写myClass对象的时候(writeObejct方法中)将这个SerializableUID首先写在流中,之后是myClass的bye流。

2,在读取myClass对象的时候(readObject()方法中)首先读出这个SerializableUID,之后在JavaVM中检索是否存在和这个UID对应的实现了Serializable接口的类。如果存在,则正常读出一个该类的实例,否则会收到一个InvalidClassException。

PS:指定UID的时候要注意,不支持Serializable接口的所有Class默认的SerializableUID都是0L(long型哦!)。

当然,建议终究是建议,如果不指定的话java.io.ObjectStreamClass类中提供了computeDefaultSUID()方法给没有SerializableUID又实现了Serializable接口的Class计算一个默认的SerializableUID,在写的时候(writeObejct方法中)会算一下写到流中,读的时候(readObject()方法中)再算一下看看是否相等。

具体实现方式可以参考java.io.ObjectStreamClass类,基本上还是按照类的结构,还有参数内容,类型计算出来的,尽量保证(不一定肯定能保证,推荐你自己写一个都...)不会出现类不一样UID一样的情况。

Java.io.ObjectStreamClass这个类感觉是为序列化专用的类,主要作用就是和JavaVM通信,里面的一个方法lookup()非常有用,用于检查在当前VM中是否存在某个类。在读取对象的时候就是使用这个方法的。

Java实现类的序列化不仅有Serializable,还有Externalizable接口,Externalizable是Serializable的子接口。实现Externalizable必须手动实现readExternal和writeExternal两个方法,在读写对象的时候会调用这两个方法进行对象的读写。如果继承的是Serializable接口,读些对象的时候调用的就是writeObject()和readObject()方法了。

如果想控制对象是如何序列化的,那么就用Externalizable吧!

//转载http://blog.csdn.net/eadber/article/details/2347167
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐