java 序列化

参见:

https://www.runoob.com/java/java-serialization.html

 

Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。
整个过程都是 Java 虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。

ObjectInputStream ObjectOutputStream 是高层次的数据流,

它们包含反序列化和序列化对象的方法。
ObjectOutputStream 类包含很多写方法来写各种数据类型,但是一个特别的方法例外:
public final void writeObject(Object x) throws IOException
上面的方法序列化一个对象,并将它发送到输出流。相似的 ObjectInputStream 类包含如下反序列化一个对象的方法:
public final Object readObject() throws IOException, ClassNotFoundException
该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。

为了演示序列化在Java中是怎样工作的,我将使用之前教程中提到的Employee类,假设我们定义了如下的Employee类,该类实现了Serializable 接口。

Employee.java 文件代码:
package serializableTest;
import java.io.Serializable;
public class Employee implements Serializable {
    public String name, address;
    public transient int SSN;
    public int number;
    public void mailCheck() {
        System.out.println("Mailing a check to: " + name + " " + address);
    }
}

SerializeDemo.java 文件代码:
package serializableTest;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SerializeDemo {
    public static void main(String[] args) {
        Employee employee = new Employee();
        employee.name = "Allen";
        employee.address = "Hai Dian District";
        employee.SSN = 112233;
        employee.number = 101;
        String filePath = "D:\\SerailiedEmployee.ser";
        try {
            FileOutputStream fileOut = new FileOutputStream(filePath);
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(employee); //把 employee 实例导出了
            out.close();
            System.out.println("Serialized data is saved in SerailiedEmployee.ser");
        } catch (Exception e) {
                e.printStackTrace();
        }
    }
}

DeserializeDemo.java 文件代码:
package serializableTest;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class DeserializeDemo {
    public static void main(String[] args) {
        Employee e = null;
        String filePath = "D:\\SerailiedEmployee.ser";
        try {
            FileInputStream fileIn = new FileInputStream(filePath);
            ObjectInputStream in = new ObjectInputStream(fileIn);
            e = (Employee)in.readObject();
            in.close();
            fileIn.close();
        } catch (Exception e2) {
            e2.printStackTrace();
        }
        System.out.println("Deserialized Employee...");
        System.out.println("Name: " + e.name);
        System.out.println("Address: " + e.address);
        System.out.println("SSN: " + e.SSN);
        System.out.println("Number: " + e.number);
    }
}
结果:
Deserialized Employee...
Name: Allen
Address: Hai Dian District
SSN: 0
Number: 101

这里要注意以下要点:
readObject() 方法中的 try/catch代码块尝试捕获 ClassNotFoundException 异常。对于 JVM 可以反序列化对象,它必须是能够找到字节码的类。如果JVM在反序列化对象的过程中找不到该类,则抛出一个 ClassNotFoundException 异常。
注意,readObject() 方法的返回值被转化成 Employee 引用。
当对象被序列化时,属性 SSN 的值为 1112233,但是因为该属性是短暂(transient)的(也就是为了安全考虑,不把他的具体值放到序列化文件中),该值没有被发送到输出流。所以反序列化后 Employee 对象的 SSN 属性为 0。

posted @ 2019-06-23 07:21  allenbackpacker  阅读(296)  评论(0编辑  收藏  举报