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

java.io.Serializable与java.io.Externalizable的比较
      当两个进程在进行远程通信时,无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送,称为对象的序列化;接收方则需要把字节序列再恢复为Java对象,称为对象的反序列化。 只有实现了Serializable和Externalizable接口的类的对象才能被序列化,而Externalizable接口又继承自Serializable接口。下面是序列化和外部化接口代码:
SerializableMyTest
 1package serializableTest;
 2
 3import java.io.FileInputStream;
 4import java.io.FileOutputStream;
 5import java.io.ObjectInputStream;
 6import java.io.ObjectOutputStream;
 7import java.io.Serializable;
 8import java.util.Date;
 9
10public class SerializableMyTest {
11
12    public static void main(String[] args) throws Exception {
13        // TODO Auto-generated method stub
14        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
15                "shit.obj"));
16        Customer customer = new Customer("Gefforey"23);
17        out.writeObject("Hello,gefforey");
18        out.writeObject(new Date());
19        out.writeObject(customer);
20        out.writeInt(520);
21        out.close();
22
23        System.out.println();
24        ObjectInputStream in = new ObjectInputStream(new FileInputStream(
25                "shit.obj"));
26        System.out.println("obj1=" + (String) in.readObject());
27        System.out.println("obj2=" + (Date) in.readObject());
28        System.out.println("obj3:" + (Customer) in.readObject());
29        System.out.println("obj4=" + in.readInt());
30        in.close();
31    }

32}

33
34class Customer implements Serializable {
35    public String name;
36
37    public int age;
38
39    public Customer(String name, int age) {
40        this.name = name;
41        this.age = age;
42    }

43
44    public String toString() {
45        return "name=" + name + ",age=" + age + ".";
46    }

47}

48
obj1=Hello,gefforey
obj2=Sat Jun 20 17:32:20 CST 2009
obj3:name=Gefforey,age=23.
obj4=520

AppTest
  1package serializableTest;
  2
  3import java.io.Externalizable;
  4import java.io.FileInputStream;
  5import java.io.FileOutputStream;
  6import java.io.IOException;
  7import java.io.ObjectInput;
  8import java.io.ObjectInputStream;
  9import java.io.ObjectOutput;
 10import java.io.ObjectOutputStream;
 11import java.io.Serializable;
 12
 13
 14//必须得实现Serializable接口
 15//writing aborted; java.io.NotSerializableException: serializableTest.Customer2
 16class Customer2 implements Serializable {
 17    public String name;
 18
 19    public int age;
 20
 21    @Override
 22    public int hashCode() {
 23        final int PRIME = 31;
 24        int result = 1;
 25        result = PRIME * result + age;
 26        result = PRIME * result + ((name == null? 0 : name.hashCode());
 27        return result;
 28    }

 29
 30    @Override
 31    public boolean equals(Object obj) {
 32        if (this == obj)
 33            return true;
 34        if (obj == null)
 35            return false;
 36        if (getClass() != obj.getClass())
 37            return false;
 38        final Customer2 other = (Customer2) obj;
 39        if (age != other.age)
 40            return false;
 41        if (name == null{
 42            if (other.name != null)
 43                return false;
 44        }
 else if (!name.equals(other.name))
 45            return false;
 46        return true;
 47    }

 48
 49    public Customer2(String name, int age) {
 50        this.name = name;
 51        this.age = age;
 52    }

 53
 54    public String toString() {
 55        return "name=" + name + ",age=" + age + ".";
 56    }

 57}

 58
 59
 60/**//*
 61 * 相当于要序列化得类
 62 */

 63class Customer3 implements Externalizable // Test类必须实现Externalizable接口
 64    private String letterstates = "gefforey";
 65
 66    private int num = 0;
 67    
 68    //要序列化得类中还可以加需要序列化的类,Customer2也要实现Serilizable接口
 69    private Customer2 cus =new Customer2("ffffffffff",24);
 70
 71    public Customer3() {
 72    }

 73
 74    public void writeExternal(ObjectOutput out) throws IOException {
 75        out.writeObject(letterstates);
 76        out.write(88); // 在序列化的数据最后加个88
 77        out.writeObject(cus);
 78        System.out.println("in writeExternal---"+cus.hashCode());
 79    }

 80
 81    public void readExternal(ObjectInput in) throws IOException,
 82            ClassNotFoundException {
 83        letterstates = (String) in.readObject();
 84        num = in.read(); // 把数字88加进来
 85        Customer2 cusTemp = (Customer2) in.readObject();
 86        System.out.println("cus==cusTemp---"+(cus==cusTemp));
 87        System.out.println("in readExternal---"+cus.hashCode());
 88        
 89    }

 90
 91    public void printOut() // 测试
 92        System.out.println(letterstates +"--"+num);
 93    }

 94}

 95
 96public class AppTest {
 97    private void saveGame() {
 98        Customer3 m = new Customer3();
 99        if (m != null{
100            try {
101                FileOutputStream ostream = new FileOutputStream("t.txt");
102                ObjectOutputStream p = new ObjectOutputStream(ostream);
103
104                p.writeObject(m); // writeExternal()自动执行
105
106                p.flush();
107                ostream.close();
108            }
 catch (IOException ioe) {
109                System.out.println("Error saving file:");
110                System.out.println(ioe.getMessage());
111            }

112        }

113    }

114
115    private void loadGame() {
116        try {
117            FileInputStream instream = new FileInputStream("t.txt");
118            ObjectInputStream p = new ObjectInputStream(instream);
119            Customer3 m = (Customer3) p.readObject();// readExternal()自动执行
120            m.printOut();
121            instream.close();
122        }
 catch (Exception e) {
123            System.out.println("Error loading file:");
124            System.out.println(e.getMessage());
125        }

126    }

127
128    public static void main(String[] args) {
129        new AppTest().saveGame();
130        new AppTest().loadGame();
131    }

132}

133
in writeExternal----1524332777
cus==cusTemp---false
in readExternal----1524332777
gefforey--88

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

每个接口的优点和缺点

Serializable接口

· 优点:内建支持

· 优点:易于实现

· 缺点:占用空间过大

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

Externalizable接口

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

· 优点:可能的速度提升

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

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

你可能感兴趣的:(java.io.Serializable与java.io.Externalizable的比较)