java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java transient 关键字

JAVA transient 关键字作用详解

作者:猩火燎猿

Java的transient关键字用于修饰成员变量,使其不参与序列化过程,通过自定义序列化方法,可以手动控制transient变量的序列化行为,本文给大家介绍JAVA transient 关键字作用,感兴趣的朋友跟随小编一起看看吧

一、transient关键字作用

二、原理详解

Java 的对象序列化机制(如 ObjectOutputStream)会将对象的所有非静态、非瞬态(transient)成员变量序列化到字节流中。
transient 关键字告诉 JVM:该变量是临时的,不需要序列化。

反序列化时transient 变量会被赋予默认值(如 int 为 0,引用类型为 null)。

三、典型使用场景

四、代码示例

import java.io.*;
class User implements Serializable {
    private String username;
    private transient String password; // 不序列化
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}
public class TransientDemo {
    public static void main(String[] args) throws Exception {
        User user = new User("Tom", "123456");
        // 序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.obj"));
        oos.writeObject(user);
        oos.close();
        // 反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.obj"));
        User user2 = (User) ois.readObject();
        ois.close();
        System.out.println(user2.username); // Tom
        System.out.println(user2.password); // null
    }
}

五、注意事项

  1. 只修饰变量,不能修饰方法、类、局部变量。
  2. 静态变量不参与序列化,即使没有 transient 修饰,也不会被序列化。
  3. 自定义序列化:如果实现了 writeObject 和 readObject,可以手动控制 transient 变量的序列化行为。

六、与 static 的区别

七、面试常见问题

八、补充:自定义序列化 transient 变量

如果你想让 transient 变量也能序列化,可以自定义 writeObject/readObject:

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

九、总结表

特性说明
作用标记变量不参与序列化
默认值反序列化后为默认值
修饰对象只能修饰成员变量
典型场景敏感信息/临时变量/不可序列化对象
可否自定义可通过 writeObject/readObject 手动处理

十. 序列化机制与 transient 的底层原理

Java 的序列化机制通过 ObjectOutputStream 和 ObjectInputStream 实现。序列化时,JVM 会遍历对象的所有字段,只有满足以下条件的字段才会被序列化:

transient 的本质
JVM 在序列化对象时,会判断字段是否被 transient 修饰,如果是,则跳过该字段,不写入字节流。

十一. 常见误区与陷阱

误区一:transient 修饰的变量绝对不会被序列化

实际情况:如果你自定义了 writeObject/readObject 方法,可以手动序列化 transient 字段。

误区二:transient 只能用于敏感信息

实际情况:transient 还可以用于临时计算、缓存、不可序列化成员等场景。

误区三:static transient 有意义

实际情况:static 字段本身就不会被序列化,transient 修饰 static 字段没有任何作用。

十二. 进阶应用:自定义序列化 transient 字段

有时你希望 transient 字段能被序列化,但不想默认序列化,可以自定义序列化方法:

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject(); // 序列化非transient字段
    oos.writeObject(this.transientField); // 手动序列化transient字段
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject(); // 反序列化非transient字段
    this.transientField = (Type) ois.readObject(); // 手动反序列化transient字段
}

十三. 实际应用场景扩展

十四. 面试陷阱代码分析

陷阱一:

class Test implements Serializable {
    private transient int a = 10;
    private int b = 20;
}

如果序列化后反序列化,a 的值是多少?
答案: 0(int 默认值),b 是 20。

陷阱二:

class Test implements Serializable {
    private static transient int a = 10;
}

序列化后反序列化,a 的值是多少?
答案: 10(static 字段不会被序列化,值取决于类加载时的静态初始化)

十五. transient 与其他关键字的对比

关键字作用是否序列化
transient标记不序列化成员变量
static类变量,不属于对象
final常量,只能赋值一次

十六. 进阶:transient 与可变对象

如果 transient 修饰的是引用类型变量(如 List),反序列化后会变为 null。
如果需要恢复数据,可以在 readObject 方法里初始化或重建。

十七. 典型面试题总结

十八. 补充:序列化版本号与 transient

十九.transient与序列化机制的深层关系

1 序列化的过程

2 反序列化过程

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    this.transientField = ...; // 这里可以初始化
}

二十.transient相关的安全问题

1 敏感数据泄露

2 反序列化漏洞

二十一. 性能优化相关

二十二. 在主流框架中的应用

1 Spring

2 Hibernate/JPA

3 分布式缓存/消息队列

二十三. 进阶:transient 与自定义序列化框架

二十四. 面试高频“陷阱”与实战建议

1 面试陷阱代码

class Person implements Serializable {
    private transient int age = 18;
    private String name = "Tom";
}

序列化后反序列化,age 是多少?
答案:0(int 默认值),不是 18。

2 实战建议

二十五. 结合实际业务场景举例

1 缓存对象

class CacheObject implements Serializable {
    private String data;
    private transient long lastAccessTime; // 仅本地有效
}

2 日志字段

class ServiceBean implements Serializable {
    private String id;
    private transient Logger log = LoggerFactory.getLogger(ServiceBean.class);
}

3 线程池、数据库连接等资源

class Job implements Serializable {
    private transient ExecutorService threadPool;
    private transient Connection dbConn;
}

二十六. 小结

到此这篇关于JAVA transient 关键字详解的文章就介绍到这了,更多相关java transient 关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文