Java序列化和反序列化——田少嵩

Posted tarena_3G

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java序列化和反序列化——田少嵩相关的知识,希望对你有一定的参考价值。

1.序列化/反序列化一个未实现序列化接口的类型对象

如果这个类(称其为A类)提供了带参数的构造器,那么可以创建一个实现了序列化接口的新类(称其为B类)。B类中用属性来持有创建A类对象所需要的那些参数。这样问题就从序列化/反序列化一个A类对象转为了序列化/反序列化创建一个A类对象所需要的参数。

示例代码如下:

[java]  view plain  copy
  1. public class A   
  2.    private String name;  
  3.    private int age;  
  4.    
  5.    public A(int age, String name)   
  6.        this.age = age;  
  7.        this.name = name;  
  8.       
  9.    
  10.    public int getAge()   
  11.        return age;  
  12.       
  13.    
  14.    public String getName()   
  15.        return name;  
  16.       
  17.    
  18.    @Override  
  19.    public String toString()   
  20.        return "A" +  
  21.                 "age=" + age +  
  22.                 ", name='" + name +'\\'' +  
  23.                 '';  
  24.       
  25.   

A类没有实现序列化接口。

设计一个B类“持有”一个A类,并且实现了序列化接口。当需要序列化一个A类对象的时候,可以通过一个序列化一个B对象,来序列化A对象的属性内容。

[java]  view plain  copy
  1. public class B implements Serializable  
  2.    private String name;  
  3.    private int age;  
  4.    private A a;  
  5.    
  6.    public B(String name, int age)   
  7.        this.name = name;  
  8.        this.age = age;  
  9.       
  10.    private void writeObject(ObjectOutputStream out) throws IOException  
  11.        out.writeUTF(name);  
  12.        out.writeInt(age);  
  13.       
  14. private voidreadObject(ObjectInputStream in)  
  15.  throwsIOException,ClassNotFoundException  
  16.        name = in.readUTF();  
  17.        age = in.readInt();  
  18.        a = new A(age,name);  
  19.       
  20.    public String toString()   
  21.        return "Ba= " + a + ", name='" + name + '\\'' +", age=" + age + '';  
  22.       
  23.    public A getA()  
  24.        return new A(age,name);  
  25.       
  26.   


这里需要注意的是B类里面有两个“特殊”的方法writeObject(ObjectOutputStream)和readObject(ObjectInputStream),当进行序列化/反序列化操作的时候,如果Java发现要序列化/反序列化的对象包含这样两个方法,则会优先使用这两个方法进行序列化/反序列化操作。即序列化B对象的时候,会调用B类的writeObject方法来进行而不使用ObjectOutputStream的writeObject方法。反序列化B对象的时候,会调用B类的readObject方法来进行而不使用ObjectInputStream的readObject方法。另外,通过ObjectOutputStream和ObjectInputStream包含的writeXXX方法和readXXX方法,可以知道尽管ObjectOutputStream继承自OutputStream,但是它的行为方式却是FilterOutputStream,ObjectInputStream也是这样的。而且与DataOutputStream/DataInputStream更加类似的是,反序列化时的读取属性顺序要与序列化时的存储属性顺序和方式一致。

下面是使用B类对象来间接序列化/反序列化A类对象的代码示例:

[java]  view plain  copy
  1. public class ObjectStreamTest   
  2.    public static void main(String[] args) throws Exception   
  3.        ObjectOutputStream out =  
  4. new ObjectOutputStream(new FileOutputStream("d:/test.dat"));  
  5.        A a = new A(29,"Tony");  
  6.        B b = new B(a.getName(),a.getAge());  
  7.        out.writeObject(b);  
  8.        out.close();  
  9.        out = null;  
  10.        System.out.println("序列化完毕");  
  11.        ObjectInputStream in = new ObjectInputStream(new FileInputStream("d:/test.dat"));  
  12.        B bb = (B) in.readObject();  
  13.        System.out.println(bb);  
  14.        System.out.println(bb.getA());  
  15.        in.close();  
  16.       
  17.   


2.外部化 Externalization

可以把外部化看做一种自定义式的序列化操作。一个类实现了Externalizable接口就意味着这个类的对象是外部化的。Externalizable接口中有两个抽象方法writeExternal和readExternal,分别用来序列化和反序列化一个可外部化的对象时被调用。

下面是外部化类对象的使用示例:

[java]  view plain  copy
  1. public class A implements Externalizable  
  2.    private String name;  
  3.    private int age;  
  4.    public A()   
  5.       
  6.    public A(int age, String name)   
  7.        this.name = name;  
  8.        this.age = age;  
  9.       
  10.    public int getAge()   
  11.        return age;  
  12.       
  13.    public String getName()   
  14.        return name;  
  15.       
  16.    @Override  
  17.    public String toString()   
  18.        return "A" +  
  19.                 "age=" + age +  
  20.                 ", name='"Java的序列化和反序列化

    Java的序列化和反序列化

    什么是java的序列化和反序列化?

    Java 序列化和反序列化Serializable 源码分析 - 1

    java 序列化和反序列化

    Java序列化和反序列化