如果需要使用ObjectInputStream和ObjectOuputStream的readObject以及writeObject()方法写入和读取非Java的基础类,需要对该类进行序列化。
例如,如果需读写String,数组,枚举类型以及Java的基本数据类型,
则不需要做其他额外操作可以直接使用readObject()和writeObject()方法读取。
如果是自己创建的Class,那就不行啦,会得到一个NotSerializableException。
解决方法呢,就是给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吧!
例如,如果需读写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吧!