Java对象序列化

序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候又可再获得,就好比hibernate将对象保存到数据库中。类通过实现 java.io.Serializable 接口以启用其序列化功能。此接口没有方法或字段,仅用于标识可序列化的语义。序列化的过程就是对象写入字节流和从字节流中读取对象。将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,管道到另一 线程中或通过网络连接将对象数据发送到另一主机。对象序列化功能非常简单、强大,在RMI、Socket、JMS、EJB都有应用。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态, transient代表对象的临时数据。


什么情况下需要序列化

当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;

当你想用套接字在网络上传送对象的时候;

当你想通过RMI传输对象的时候;

 

在序列化时,有几点要注意的:
1:当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
2:如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
3:如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化
还有我们对某个对象进行序列化时候,往往对整个对象全部序列化了,比如说类里有些数据比较敏感,不希望序列化,一个方法可以用transient来标识,另一个方法我们可以在类里重写

1.实现Serializable回导致发布的API难以更改,并且使得package-private和private这两个本来封装的较好的咚咚也不能得到保障了
2.Serializable会为每个类生成一个序列号,生成依据是类名、类实现的接口名、public和protected方法,所以只要你一不小心改了一个已经publish的API,并且没有自己定义一个long类型的叫做serialVersionUID的field,哪怕只是添加一个getXX,就会让你读原来的序列化到文件中的东西读不出来(不知道为什么要把方法名算进去?)
3、不用构造函数用Serializable就可以构造对象,看起来不大合理,这被称为extralinguistic mechanism,所以当实现Serializable时应该注意维持构造函数中所维持的那些不变状态
4、增加了发布新版本的类时的测试负担
5.1.4版本后,JavaBeans的持久化采用基于XML的机制,不再需要Serializable
6.设计用来被继承的类时,尽量不实现Serializable,用来被继承的interface也不要继承Serializable。但是如果父类不实现Serializable接口,子类很难实现它,特别是对于父类没有可以访问的不含参数的构造函数的时候。所以,一旦你决定不实现Serializable接口并且类被用来继承的时候记得提供一个无参数的构造函数
7.内部类还是不要实现Serializable好了,除非是static的
8.不管你选择什么序列化形式,声明一个显式的UID:private static final long serialVersionUID = randomLongValue;

public class Person implements Serializable {
 
    private static final long serialVersionUID = -8991721997950115500L;
 
    private String name;
    transient private int age;// 此处标明age属性不能保存
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String toString() {
        return "姓名:" + this.name + ",年龄:" + this.age;
    }
 
    public static void main(String[] args) throws Exception {
 
        // 对p对象序列化,p对象二进制文件保存到d:中,用到OjbectOutputStream类
        File file = new File("d:" + File.separator + "person.abc");
        ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(
                file));
        Person p = new Person("ljfbest.com", 200);
        os.writeObject(p);
        os.close();
 
        // 把序列化
        ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
        Object obj = is.readObject();
        Person per = (Person) obj;
        System.out.println(per);// 打印: 姓名:ljfbest,年龄:0
    }
}

IBM上关于java序列化的一篇文章
http://www.ibm.com/developerworks/cn/java/j-5things1/index.html#ibm-pcon

你可能感兴趣的:(Java对象序列化)