java中的序列化

序列化

Java 的序列化就是将一个 Java 对象转化为一个字节流的一种机制。从字节流再转回 Java 对象叫做反序列化,是序列化的反向操作。

序列化和反序列化是和平台无关的,也就是说你可以在 Linux 系统序列化,然后在 Windows 操作系统做反序列化。

如果要序列化对象,需要使用 ObjectOutputStream 类的 writeObject() 方法。如果要做反序列化,则要使用 ObjectOutputStream 类的 readObject() 方法。

如下图所示,对象被转化为字节流后,被储存在了不同的介质中。这个流程就是序列化。在图的右边,也可以看到从不同的介质中,比如内存,获得字节流并转化为对象,这叫做反序列化。
java中的序列化

为什么使用序列化

如果我们创建了一个 Java 对象,这个对象的状态在程序执行完毕或者退出后就消失了,不会得到保存。

所以,为了能解决这类问题,Java 提供了序列化机制。这样,我们就能把对象的状态做临时储存或者进行持久化,以供后续当我们需要这个对象时,可以通过反序列化把对象还原回来。

下面给出一些代码看看我们是怎么来做序列化的。

import java.io.Serializable;

public class Player implements Serializable {

    private static final long serialVersionUID = 1L;

    private String serializeValueName;
    private transient String nonSerializeValuePos;

    public String getSerializeValueName() {
        return serializeValueName;
    }

    public void setSerializeValueName(String serializeValueName) {
        this.serializeValueName = serializeValueName;
    }

    public String getNonSerializeValueSalary() {
        return nonSerializeValuePos;
    }

    public void setNonSerializeValuePos(String nonSerializeValuePos) {
        this.nonSerializeValuePos = nonSerializeValuePos;
    }

    @Override
    public String toString() {
        return "Player [serializeValueName=" + serializeValueName + "]";
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializingObject {
    public static void main(String[] args) {

        Player playerOutput = null;
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;

        playerOutput = new Player();
        playerOutput.setSerializeValueName("niubi");
        playerOutput.setNonSerializeValuePos("x:1000,y:1000");

        try {
            fos = new FileOutputStream("Player.ser");
            oos = new ObjectOutputStream(fos);
            oos.writeObject(playerOutput);

            System.out.println("序列化数据被存放至Player.ser文件");

            oos.close();
            fos.close();

        } catch (IOException e) {

            e.printStackTrace();
        }
    }
}

Output:
序列化数据被存放至Player.ser文件

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeSerializingObject {

    public static void main(String[] args) {

        Player playerInput = null;
        FileInputStream fis = null;
        ObjectInputStream ois = null;

        try {
            fis = new FileInputStream("Player.ser");
            ois = new ObjectInputStream(fis);
            playerInput = (Player) ois.readObject();

            System.out.println("从Player.ser文件中恢复");

            ois.close();
            fis.close();

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("player名字为 : " + playerInput.getSerializeValueName());
        System.out.println("player位置为 : " + playerInput.getNonSerializeValuePos());
    }
}

Output:

从Player.ser文件中恢复
player名字为 : niubi
player位置为 : null

关键特性

  1. 如果父类实现了 Serializable 接口那么子类就不必再实现 Serializable 接口了。但是反过来不行。
  2. 序列化只支持非 static 的成员变量
  3. static 修饰的变量和常量以及被 transient 修饰的变量是不会被序列化的。所以,如果我们不想要序列化某些非 static 的成员变量,直接用 transient 修饰它们就好了。
  4. 当反序列化对象的时候,是不会调用对象的构造函数的。
  5. 如果一个对象被一个要序列化的对象引用了,这个对象也会被序列化,并且这个对象也必须要实现 Serializable 接口。
上一篇:视频播放器之————JW Player参数详解


下一篇:利用windows服务实现整点报时功能