Serializable 和 serialVersionUID
2012-10-12 16:19
405 查看
如果需要使用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吧!
//转载http://blog.csdn.net/eadber/article/details/2347167
例如,如果需读写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
相关文章推荐
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于Serializable的serialVersionUID
- Serializable兼容性问题及serialVersionUID的使用
- Serializable兼容性问题及serialVersionUID的使用
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- serializable 类 ****未声明类型为 long 的静态终态 serialVersionUID 字段
- The serializable class Myplayer does not declare a static final serialVersionUID field of type long
- 编译环境提The serializable class XXX does not declare a static final serialVersionUID field of type long
- Serializable兼容性问题及serialVersionUID的使用
- The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- The serializable class XXX does not declare a static final serialVersionUID field of type long
- 问题:serializable 类 MyFrame 未声明类型为 long 的静态终态 serialVersionUID 字段
- The serializable class XXXAcion does not declare a static final serialVersionUID field of type long XXAcation.java异常坚决办法
- The serializable class Proname does not declare a static final serialVersionUID field of type long
- The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于Serializable的serialVersionUID
- Android studio实现Serializable自动生成serialVersionUID
- Java基础篇 - Serializable与serialVersionUID的简单说明