浅谈Java序列化Serializable

来源:互联网 发布:自动排班表软件 编辑:程序博客网 时间:2024/06/06 01:12

在Java中,如果我们需要把对象持久化到硬盘,或者在网络上传输,类必须实现Serializable接口,使用对象流的形式,把对象写入磁盘。

如果该类没实现Serializable接口,当调用ObjectOutputStream.writeObject的时候,JVM将会抛出java.io.NotSerializableException异常。

Java序列化有几个特征:

1.当序列化子类的时候,如果父类没有实现Serializable接口,则反序列化的时候,将调用父类的构造方法重新生成父类对象;

public class SerializableDemo {    public static void main(String[] args) {        write();        System.out.println("--------");        read();    }    static void write() {        Dog dog = new Dog();        dog.name = "Nelson";        dog.age = 13;        try {            FileOutputStream fos = new FileOutputStream("/data2/object.ser");            ObjectOutputStream oos = new ObjectOutputStream(fos);            oos.writeObject(dog);            fos.close();            oos.close();        }        catch (IOException e) {            e.printStackTrace();        }    }    static void read() {        Dog dog = null;        try {            FileInputStream fis = new FileInputStream("/data2/object.ser");            ObjectInputStream ois = new ObjectInputStream(fis);            dog = (Dog) ois.readObject();            fis.close();            ois.close();        }        catch (IOException | ClassNotFoundException e) {            e.printStackTrace();        }        System.out.println(dog.name + "," + dog.age);    }}class Animal {    String name;    int age;    public Animal() {        System.out.println("invoke Animal constructor");        this.name = "Monkey";        this.age = 100;    }}class Dog extends Animal implements Serializable {    public Dog() {        System.out.println("invoke Dog constructor");    }}

输出:

invoke Animal constructor
invoke Dog constructor
--------
invoke Animal constructor
Monkey,100


2.如果父类实现了Serializable接口,则反序列化的时候,将复用父类对象,不会重新构造父类

class Animal implements Serializable {    String name;    int age;    public Animal() {        System.out.println("invoke Animal constructor");        this.name = "Monkey";        this.age = 100;    }}class Dog extends Animal implements Serializable {    public Dog() {        System.out.println("invoke Dog constructor");    }}

输出:

invoke Animal constructor
invoke Dog constructor
--------
Nelson,13


3.如果父类已经实现了Serializable接口,则子类可以不用显式地实现Serializable接口

class Animal implements Serializable {    String name;    int age;    public Animal() {        System.out.println("invoke Animal constructor");        this.name = "Monkey";        this.age = 100;    }}class Dog extends Animal {    public Dog() {        System.out.println("invoke Dog constructor");    }}
输出:

invoke Animal constructor
invoke Dog constructor
--------
Nelson,13


4.如果A类持有B类的引用(B不为空),当序列化A类的时候,B类必须实现Serializable接口,否则JVM将会抛出java.io.NotSerializableException异常

5.当如果某个属性不想序列化,则使用transient关键字标记,当JVM序列化的时候,遇到transient关键字的属性,则会跳过此属性

class Animal implements Serializable {    transient String name;    int age;    public Animal() {        System.out.println("invoke Animal constructor");        this.name = "Monkey";        this.age = 100;    }}class Dog extends Animal {    public Dog() {        System.out.println("invoke Dog constructor");    }}
输出: 

invoke Animal constructor
invoke Dog constructor
--------
null,13

0 0
原创粉丝点击