Java 序列化注解及其使用

简介

在 Java 程序中,对象的序列化是指将对象转换为字节流的过程,以便在网络上传输或保存到文件中。而反序列化则是将字节流重新转换为对象。

Java 提供了 java.io.Serializable 接口,用于标识可序列化的类。然而,有时我们希望在序列化的过程中排除某些字段,或者对某些字段进行自定义处理。这时,我们可以使用序列化注解来实现。

常用的序列化注解

@Transient

@Transient 是javax.persistence 包中的一个注解,它用于标记不希望序列化的字段。当对象被序列化时,被标记为 @Transient 的字段将被忽略。

public class Person implements Serializable {
    private String name;
    @Transient
    private int age;
    // getter and setter methods
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

上面的代码中,age 字段被标记为 @Transient,在序列化过程中将被忽略。

@Serialize

@Serialize 是 Java 序列化中自定义的一个注解,它用来标记字段在序列化过程中需要进行特殊处理。

public class Person implements Serializable {
    private String name;
    @Serialize
    private Date birthDate;
    // getter and setter methods
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

上述代码中,birthDate 字段被标记为 @Serialize,在序列化过程中将被特殊处理。

@Serial

在 Java 序列化中,如果需要自定义序列化和反序列化的过程,可以使用 @Serial 注解。

public class Person implements Serializable {
    private String name;
    @Serial
    private int age;
    // getter and setter methods
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeInt(age);
    }
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        age = in.readInt();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

上述代码中,writeObject 方法用来自定义序列化过程,readObject 方法用来自定义反序列化过程。通过 @Serial 注解,我们可以自行控制序列化和反序列化的细节。

序列化与反序列化示例

下面是一个示例代码,演示了如何使用序列化注解来实现对象的序列化和反序列化。

import java.io.*;
public class SerializationExample {
    public static void main(String[] args) {
        // 创建一个 Person 对象
        Person person = new Person();
        person.setName("Alice");
        person.setAge(25);
        // 将对象序列化到文件中
        serialize(person, "person.ser");
        // 从文件中反序列化对象
        Person deserializedPerson = deserialize("person.ser");
        // 打印反序列化后的对象
        System.out.println("Name: " + deserializedPerson.getName());
        System.out.println("Age: " + deserializedPerson.getAge());
    }
    private static void serialize(Object object, String fileName) {
        try (FileOutputStream fileOut = new FileOutputStream(fileName);
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            out.writeObject(object);
            System.out.println("Serialized data is saved in " + fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static <T> T deserialize(String fileName) {
        T object = null;
        try (FileInputStream fileIn = new FileInputStream(fileName);
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            object = (T) in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return object;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.

上面的代码中,我们创建了一个 Person 对象,并将其序列化到文件 person.ser 中。然后,我们使用 deserialize 方法从文件中反序列化对象,并打印出反序列化后的结果。

总结

序列化注解提供了一种灵活的方式来控制对象的序列化和反序列化过程。通过使用 @Transient 注解,我们可以排除不需要序列化的字段;通过使用 @Serialize 注解,我们可以对需要特殊处理的字段进行标记;而通过使用 @Serial 注解,我们可以自定义序列化和反序列化的过程。

通过本文