Java中序列化与反序列化的学习

对象序列化和反序列化


Java对象序列化(Serialization)和反序列化(Deserialization)是Java提供的一种机制,允许你将一个对象的状态保存到一个字节序列中,并能从这个字节序列中恢复出原始对象。这种机制主要用于对象的持久化存储(如保存到文件中),或在网络中传输对象。

序列化

序列化是将对象状态转换为可以保存或传输的格式的过程。在Java中,一个对象想要被序列化,需要满足以下条件:

  1. 实现Serializable接口:该接口是一个标记接口(不包含任何方法的接口),用于指示该类的对象可以被序列化。
  2. 所有非瞬态(non-transient)的实例变量:实例变量(除非被标记为transient)都会被序列化。transient关键字用于声明不需要序列化的字段。

示例代码:

import java.io.Serializable;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;

public class Employee implements Serializable {
    private static final long serialVersionUID = 1L; // 用于版本控制
    private String name;
    private transient int age; // 这个字段不会被序列化

    // 构造器、getter和setter省略

    public static void main(String[] args) {
        Employee emp = new Employee();
        emp.setName("John Doe");
        emp.setAge(30);

        try (FileOutputStream fileOut = new FileOutputStream("employee.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            out.writeObject(emp);
            System.out.println("Serialized data is saved in employee.ser");
        } catch (IOException i) {
            i.printStackTrace();
        }
    }
}

反序列化

反序列化是序列化的逆过程,即从字节序列中恢复出原始对象。

示例代码:

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

public class Deserialize {
    public static void main(String[] args) {
        Employee emp = null;

        try (FileInputStream fileIn = new FileInputStream("employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            emp = (Employee) in.readObject();
            System.out.println("Deserialized Employee...");
            System.out.println("Name: " + emp.getName());
            // 注意:age字段不会被反序列化,因为它被标记为transient
        } catch (IOException i) {
            i.printStackTrace();
            return;
        } catch (ClassNotFoundException c) {
            System.out.println("Employee class not found");
            c.printStackTrace();
            return;
        }
    }
}

注意事项

  1. 安全性:反序列化可以执行任意代码,如果反序列化的对象来自不受信任的源,可能会引发安全漏洞。
  2. 版本控制serialVersionUID用于版本控制,确保序列化和反序列化的类版本兼容。如果序列化后的对象与反序列化时类的定义不一致(如类名、字段等改变),但serialVersionUID相同,则仍然可以反序列化成功。
  3. transient关键字:用于标记不需要序列化的字段。
  4. 继承:如果子类实现了Serializable接口,但父类没有,那么父类的非static、非transient字段仍会被序列化。但如果父类实现了Serializable接口,子类即便没有显式实现,也会被视作实现了该接口。

Java对象序列化和反序列化是Java编程中非常有用的特性,但需要谨慎使用,特别是在处理外部数据源时。

posted @ 2024-09-30 15:55  BingBing爱化学-04044  阅读(27)  评论(0)    收藏  举报