Java IO 7-序列化反序列化与transient关键字

  序列化这个概念在所有的项目开发中都有。

1. 序列化概念

  对象序列化指的是:将内存中保存的对象变为二进制数据流的形式进行传输,或者是将这个二进制数据流保存在文本中。

  但这并不意味着所有类的对象都需要被序列化,严格来讲,需要被序列化的类对象往往需要传输使用,同时这个类必须实现java.io.Serializable接口。

  Serializable接口是一个标识接口,里面没有任何方法,继承它的类意味着要被序列化。

public interface Serializable {
}

  序列化对象时所需要保存的就是对象中的属性,所以默认情况下对象的属性将被转为二进制数据流存在。

2. 序列化与反序列化操作

  这里我们将序列化的数据保存在文件中以方便演示。

  序列化本质就是将继承了Serializable接口的类的属性信息转化为二进制信息,而反序列化与之相反,把序列化的二进制信息转化为类的信息。

  如果要想实现序列化与反序列化的对象操作,在java.io包中提供有两个处理类:ObjectOutputStream,ObjectInputStream,如下所示:

public class ObjectOutputStream
    extends OutputStream implements ObjectOutput, ObjectStreamConstants

public class ObjectInputStream
    extends InputStream implements ObjectInput, ObjectStreamConstants

它们的继承结构如下:

  • ObjectOutputStream

序列化

  • ObjectInputStream

反序列化

  序列化和反序列化操作:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 测试路径:E:\IO\demo.txt
 */

@SuppressWarnings("serial")
class Person implements Serializable {
    private String name;
    private int age;

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "[name: "+this.name+", age: "+this.age+"]";
    }

}

public class Test {
    public static final File file = new File("E:\\IO\\demo.txt");
    public static void main(String[] args) throws Exception {
        Person person = new Person("xucc", 10);
        // 序列化
        serialization(person);
        // 反序列化,并在控制台中打印信息
        deserialization(person);
    }

    // 序列化
    public static void serialization(Object obj) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(obj);
        // 关闭流
        oos.close();
    }

    // 反序列化
    public static void deserialization(Object obj) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        System.out.println(ois.readObject());
        ois.close();
    }
}

运行程序前测试文件夹:

运行前测试文件夹

运行后转化的二进制序列化信息:

序列化二进制信息

控制台打印出的反序列化信息:

反序列化信息

3. transient关键字

  在序列化时,实现了Serializable接口的类,JVM会默认将对象中所有属性进行序列化保存,如果现在某些属性不希望被保存了,那么就可以使用transient关键字屏蔽该属性的序列化。

  以上面程序为例,修改其中的Person类

class Person implements Serializable {
    private String name;
    // 使用 transient关键字 修饰该属性,该属性将不被序列化
    private transient int age;

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "[name: "+this.name+", age: "+this.age+"]";
    }

}

运行程序后控制台信息为:

运行结果

  因为 age 被 transient 修饰了,所以该属性的值显示为 int 类型的默认值 0。

  但是在实际工程中,大部分情况下使用序列化往往是在简单java类上,其他类上使用序列化的操作模式相对较少。

  而如果是简单java类,也就很少去使用transient关键字了,了解即可。

猜你喜欢

转载自blog.csdn.net/weixin_40739833/article/details/80428384
今日推荐