693 字
3 分钟
transient关键字

transient 是 Java 中的一个关键字,用于修饰类的成员变量。它的作用是指示 JVM 在序列化对象时忽略被 transient 修饰的变量。也就是说,被 transient 修饰的变量不会被序列化,也不会被持久化到文件或网络中。

序列化简介#

在 Java 中,序列化(Serialization)是指将对象的状态转换为字节流的过程,以便将其存储到文件或通过网络传输。反序列化(Deserialization)则是将字节流转换回对象的过程

Java 提供了 java.io.Serializable 接口来实现序列化。如果一个类实现了 Serializable 接口,它的对象就可以被序列化。

transient 的作用#

默认情况下,当一个对象被序列化时,它的所有非静态transient 的成员变量都会被序列化。然而,有些变量可能不适合被序列化,例如:

  • 敏感信息(如密码)。
  • 临时数据或缓存数据。
  • 依赖运行时环境的变量(如线程状态)。

通过使用 transient 关键字,可以明确告诉 JVM 在序列化时忽略这些变量。

使用示例#

import java.io.*;

class User implements Serializable {
    private String username;
    private transient String password; // 使用 transient 修饰,不会被序列化

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{username='" + username + "', password='" + password + "'}";
    }
}

public class TransientExample {
    public static void main(String[] args) {
        // 创建对象
        User user = new User("admin", "123456");

        // 序列化对象
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.txt"))) {
            oos.writeObject(user);
            System.out.println("对象已序列化");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 反序列化对象
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.txt"))) {
            User deserializedUser = (User) ois.readObject();
            System.out.println("反序列化后的对象: " + deserializedUser);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

对象已序列化
反序列化后的对象: User{username='admin', password='null'}

注意事项#

  1. 静态变量不受 transient 影响:

    • transient 只能修饰实例变量,不能修饰静态变量。
    • 静态变量属于类而不是对象,因此不会参与序列化。
  2. transient 变量的默认值:

    • 反序列化时,transient 变量会被初始化为默认值(如 null0false 等)。
  3. 自定义序列化:

    • 如果需要控制 transient 变量的序列化行为,可以实现 writeObjectreadObject 方法。

    • 示例:

      private void writeObject(ObjectOutputStream oos) throws IOException {
          oos.defaultWriteObject(); // 默认序列化
          oos.writeObject(password); // 手动序列化 password
      }
      
      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
          ois.defaultReadObject(); // 默认反序列化
          password = (String) ois.readObject(); // 手动反序列化 password
      }

使用场景#

  • 敏感信息:如密码、密钥等,避免被序列化后泄露。
  • 临时数据:如缓存数据、计算结果,不需要持久化。
  • 依赖运行时环境的变量:如线程状态、文件句柄等,无法在反序列化后恢复。
transient关键字
https://fuwari.vercel.app/posts/javatransient/
作者
Lettle
发布于
2025-03-02
许可协议
CC BY-NC-SA 4.0