📜  Java-序列化(1)

📅  最后修改于: 2023-12-03 14:42:20.355000             🧑  作者: Mango

Java 序列化

Java 序列化是将 Java 对象转换为二进制格式,以便在网络上传输或将其保存在硬盘上。Java 序列化可以将对象转换为字节数组,也可以将其存储在文件中。

序列化的优点
  • 对象的持久性:Java 序列化机制使得对象可以被永久存储,而不需要每次使用时都重新创建对象。
  • 网络通信:Java 序列化机制使得对象可以在网络上传输,不受平台的限制。
  • 分布式应用:Java 序列化机制为分布式应用提供了基础。
序列化的缺点
  • 序列化一个对象需要消耗大量的时间和空间。
  • 序列化后的二进制格式对人类不友好,不利于调试。
如何实现序列化

Java 序列化机制需要实现 Serializable 接口,该接口标记着一个类可以被序列化。如果一个类有一个属性需要被排除在序列化之外,可以将该属性标记为 transient。

下面是一个简单的示例代码:

import java.io.*;

public class SerializeDemo implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    private transient String password;

    public SerializeDemo(String name, int age, String password) {
        this.name = name;
        this.age = age;
        this.password = password;
    }

    public static void main(String[] args) {
        SerializeDemo demo = new SerializeDemo("Tom", 20, "123456");
        try {
            FileOutputStream fileOut = new FileOutputStream("demo.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(demo);
            out.close();
            fileOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,我们定义了一个类 SerializeDemo,实现了 Serializable 接口。该类有三个属性:name、age、password。其中 password 被标记为 transient,表示不将其序列化。

在 main 函数中,我们创建了一个 SerializeDemo 对象 demo,并使用 ObjectOutputStream 将其序列化并写入到文件 demo.ser 中。

反序列化

反序列化是将二进制数据转换为 Java 对象的过程。反序列化器 ObjectInputStream 可以将一个对象从文件中读取,然后将其反序列化。

下面是一个简单的示例代码:

import java.io.*;

public class DeserializeDemo {
    public static void main(String[] args) {
        SerializeDemo demo = null;
        try {
            FileInputStream fileIn = new FileInputStream("demo.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            demo = (SerializeDemo) in.readObject();
            in.close();
            fileIn.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("Name: " + demo.getName());
        System.out.println("Age: " + demo.getAge());
        System.out.println("Password: " + demo.getPassword());
    }
}

在上述代码中,我们使用 ObjectInputStream 从文件 demo.ser 中读取序列化的对象,并将其转换为 SerializeDemo 类型。通过 getName、getAge 和 getPassword 方法,我们可以获取对象的属性。

注意事项
  • 序列化和反序列化的类必须在同一个包中。
  • 如果一个类实现了 Serializable 接口,其所有子类都可以被序列化。
  • 对于静态变量,只有在实现了 Externalizable 接口的情况下才会被序列化。
  • 如果修改了一个类的实现,在反序列化之前,必须确保序列化的类文件和反序列化的类文件的版本一致,否则会出现 InvalidClassException 异常。
总结

Java 序列化机制可以方便地将对象序列化为可保存和传输的二进制格式。通过实现 Serializable 接口和 transient 关键字,可以控制序列化的行为。在反序列化时,需要注意类文件的版本兼容性问题。