java.io.Serializable与java.io.Externalizable的比较

来源:互联网 发布:ps淘宝主图制作视频 编辑:程序博客网 时间:2024/05/22 10:57

当两个进程在进行远程通信时,无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送,称为对象的序列化;接收方则需要把字节序列再恢复为Java对象,称为对象的反序列化。 只有实现了Serializable和Externalizable接口的类的对象才能被序列化,而Externalizable接口又继承自Serializable接口。下面是序列化和外部化接口代码:

1 public interface Serializable {}

2 public interface Externalizable extends Serializable {
void readExternal(ObjectInput in);
void writeExternal(ObjectOutput out);
}

下面是Serializable实现:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class SerializabeTest {

public static void main(String[] args) throws Exception{
      // TODO Auto-generated method stub
        ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("shit.obj"));
        Customer customer=new Customer("Gefforey",23);
        out.writeObject("Hello,gefforey");
        out.writeObject(new Date( ));
        out.writeObject(customer);
        out.writeInt(520);
        out.close();
    
        ObjectInputStream in=new ObjectInputStream(new FileInputStream("shit.obj"));
        System.out.println("obj1="+(String)in.readObject());
        System.out.println("obj2="+(Date)in.readObject());
        System.out.println("obj3:"+(Customer)in.readObject());
        System.out.println("obj4="+in.readInt());
        in.close();
}
}
class Customer implements Serializable{
public String name;
public int age;
public Customer(String name,int age){
      this.name=name;
      this.age=age;
}
public String toString(){
      return "name="+name+",age="+age+".";
}
}

返回结果:obj1=Hello,gefforey
obj2=Wed Sep 19 23:03:10 CST 2007
obj3:name=Gefforey,age=23.
obj4=520

下面是Externalizable实现:

import java.io.*;

class Test implements Externalizable{      //Test类必须实现Externalizable接口
private String letterstates = "gefforey";
private int num      = 0;
public Test(){
}

public void writeExternal(ObjectOutput out) throws IOException {
                  out.writeObject(letterstates);
                  out.write(88); //在序列化的数据最后加个88
}

public void readExternal(ObjectInput in) throws IOException,
        ClassNotFoundException {
                    letterstates = (String)in.readObject();
                    num = in.read();      //把数字88加进来
}
public void printOut(){ //测试
       System.out.println(letterstates +num);
}
}

public class AppTest {
            private void saveGame(){
                    Test m = new Test();
                    if (m != null){
                            try{
                                    FileOutputStream ostream = new FileOutputStream("t.txt");
                                    ObjectOutputStream p = new ObjectOutputStream(ostream);

                                    p.writeObject(m); //writeExternal()自动执行

                                    p.flush();
                                    ostream.close();
                            } catch (IOException ioe) {
                                    System.out.println ("Error saving file:");
                                    System.out.println (ioe.getMessage());
                            }
                    }
            }

            private void loadGame(){
                    try{
                            FileInputStream instream = new FileInputStream("t.txt");
                            ObjectInputStream p = new ObjectInputStream(instream);
                            Test m = (Test)p.readObject();//readExternal()自动执行
                            m.printOut();
                            instream.close();
                    } catch (Exception e) {
                            System.out.println ("Error loading file:");
                            System.out.println (e.getMessage());
      }
            }

public static void main(String[] args){
      new AppTest().saveGame();
      new AppTest().loadGame();
}
}

运行结果为:gefforey88。

序列化会自动存储必要的信息,用以反序列化被存储的实例,而外部化则只保存被存储的类的标识。当你通过java.io.Serializable接口序列化一个对象时,有关类的信息,比如它的属性和这些属性的类型,都与实例数据一起被存储起来。在选择走Externalizable这条路时,Java 只存储有关每个被存储类型的非常少的信息。

每个接口的优点和缺点

Serializable接口

· 优点:内建支持

· 优点:易于实现

· 缺点:占用空间过大

· 缺点:由于额外的开销导致速度变比较慢

Externalizable接口

· 优点:开销较少(程序员决定存储什么)

· 优点:可能的速度提升

· 缺点:虚拟机不提供任何帮助,也就是说所有的工作都落到了开发人员的肩上。

在两者之间如何选择要根据应用程序的需求来定。Serializable通常是最简单的解决方案,但是它可能会导致出现不可接受的性能问题或空间问题;在出现这些问题的情况下,Externalizable可能是一条可行之路。

原创粉丝点击