序列化与反序列化-java实现

64 阅读2分钟

序列化

  1. 实现 Serializable 接口

    • Serializable 是一个标记接口,它没有方法和字段。当一个类实现了 Serializable 接口时,它就表明自己可以被序列化。

    • 示例代码:

      java

      复制

      import java.io.Serializable;
      
      public class Person implements Serializable {
          private static final long serialVersionUID = 1L; // 序列化版本号,用于版本控制
          private String name;
          private int age;
      
          public Person(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          // Getter 和 Setter 方法省略
      }
      
    • 在这个例子中,Person 类实现了 Serializable 接口,它的对象就可以被序列化。serialVersionUID 是一个序列化版本号,它用于确保在反序列化时类的版本兼容性。如果类的结构发生变化(如添加或删除字段),应该修改这个版本号。

  2. 使用 ObjectOutputStream 进行序列化

    • 通过 ObjectOutputStream 类可以将对象序列化到文件或其他输出流中。

    • 示例代码:

      java

      复制

      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.ObjectOutputStream;
      
      public class SerializationExample {
          public static void main(String[] args) {
              Person person = new Person("Alice", 25);
      
              try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
                  oos.writeObject(person); // 将对象序列化到文件
                  System.out.println("对象序列化成功");
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      
    • 在这个例子中,创建了一个 Person 对象,并使用 ObjectOutputStream 将其序列化到名为 “person.ser” 的文件中。writeObject 方法用于将对象写入输出流。

二、反序列化

  1. 使用 ObjectInputStream 进行反序列化

    • 通过 ObjectInputStream 类可以将序列化后的数据反序列化为对象。

    • 示例代码:

      java

      复制

      import java.io.FileInputStream;
      import java.io.IOException;
      import java.io.ObjectInputStream;
      
      public class DeserializationExample {
          public static void main(String[] args) {
              try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
                  Person person = (Person) ois.readObject(); // 从文件中反序列化对象
                  System.out.println("对象反序列化成功");
                  System.out.println("姓名:" + person.getName() + ",年龄:" + person.getAge());
              } catch (IOException | ClassNotFoundException e) {
                  e.printStackTrace();
              }
          }
      }
      
    • 在这个例子中,使用 ObjectInputStream 从 “person.ser” 文件中读取序列化后的数据,并将其反序列化为 Person 对象。readObject 方法用于读取对象,由于它可能抛出 ClassNotFoundException(如果找不到对应的类),所以需要进行异常处理。

  2. 注意事项

    • 如果类中有一些字段不需要序列化,可以在字段前加上 transient 关键字。例如:

      java

      复制

      private transient String password;
      

      这样,在序列化时,password 字段不会被序列化。在反序列化时,transient 字段会被初始化为默认值(如字符串为 null,整数为 0 等)。

    • 序列化和反序列化过程中,类的结构应该保持一致。如果类的结构发生变化(如添加或删除字段),可能会导致反序列化失败。通过正确设置 serialVersionUID 可以在一定程度上解决版本兼容性问题。