Java序列化

来源:互联网 发布:java 数据级权限控制 编辑:程序博客网 时间:2024/04/29 02:17

如果需要使用ObjectInputStream和ObjectOuputStream的readObject以及writeObject()方法写入和读取非Java的基础类,需要对该类进行序列化。
例如,如果需读写String,数组,枚举类型以及Java的基本数据类型,
则不需要做其他额外操作可以直接使用readObject()和writeObject()方法读取。
如果是自己创建的Class,那就不行啦,会得到一个NotSerializableException。
比如下面的代码:

 


import java.io.*;

public class TestSerializable{
  
public static void main(String args[]){
     ObjectOutputStream out 
= null;
     myClass obj 
= new myClass("lala"28,"beijing");
     
try{      
         out 
= new ObjectOutputStream(new FileOutputStream("c:/1.txt"));
         out.writeObject(obj);
     }
catch(IOException e){
         e.printStackTrace();
     }
finally{
         
if(out != null){
             
try{
                 out.close();
             }
catch(IOException ex){
                 ex.printStackTrace();
             }

         }

         
     }

     System.out.println(
"write ok!");
  }

}


class myClass{
    
private String name;
    
private int age;
    
private String address;
    
public myClass(String name, int age, String address){
        
this.address = address;
        
this.age = age;
        
this.name = name;
    }


}



解决方法呢,就是给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吧!

原创粉丝点击