【Java 基础篇】Java transient 关键字详解:对象序列化与非序列化字段

news/2024/10/21 10:17:28/

在这里插入图片描述

在 Java 编程中,我们经常需要将对象序列化为字节流以便于存储或传输,或者将字节流反序列化为对象以恢复其状态。然而,并不是所有对象的所有属性都应该被序列化。有些属性可能包含敏感信息,或者它们只在内存中有意义。在这些情况下,我们可以使用 transient 关键字来标记属性,告诉 Java 序列化机制不要将其序列化。本文将深入介绍 transient 关键字的使用,让您完全掌握它的用法。

什么是 transient?

transient 是 Java 中的一个关键字,用于修饰类的成员变量。当一个成员变量被声明为 transient 时,它告诉 Java 虚拟机不要将其序列化。这意味着在将对象转换为字节流时,transient 修饰的成员变量将被忽略,不包含在序列化的数据中。

为什么使用 transient?

使用 transient 关键字有以下常见原因:

  1. 保护敏感信息:有些对象属性可能包含敏感信息,如密码、密钥等。通过将这些属性标记为 transient,可以确保它们在序列化过程中不被泄露。

  2. 临时状态:某些属性仅在对象的生命周期内具有意义,不需要在不同的运行时环境中保留它们的状态。将这些属性标记为 transient 可以减小序列化数据的大小,提高性能。

  3. 避免无限递归:在对象之间存在循环引用时,如果不使用 transient,Java 的默认序列化机制会导致无限递归序列化,最终导致堆栈溢出。通过标记其中一个引用为 transient,可以避免这个问题。

transient 的使用示例

让我们通过示例来了解如何使用 transient 关键字。

import java.io.*;class Person implements Serializable {private String name;private transient String password;public Person(String name, String password) {this.name = name;this.password = password;}public String getName() {return name;}public String getPassword() {return password;}
}public class SerializationExample {public static void main(String[] args) {Person person = new Person("Alice", "secretpassword");// 将对象序列化到文件try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {oos.writeObject(person);} catch (IOException e) {e.printStackTrace();}// 从文件中反序列化对象try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {Person deserializedPerson = (Person) ois.readObject();System.out.println("Name: " + deserializedPerson.getName());System.out.println("Password: " + deserializedPerson.getPassword());} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

在上面的示例中,我们创建了一个 Person 类,其中包含 namepassword 属性。password 属性被标记为 transient,这意味着它不会被序列化到文件中。当我们将 person 对象序列化并反序列化后,尽管 name 属性被成功还原,但 password 属性的值将为 null,因为它没有被序列化。

注意事项

在使用 transient 关键字时,需要注意以下事项:

  1. 默认值:被 transient 关键字修饰的属性在反序列化后会被赋予默认值。对于基本数据类型,如 intboolean,默认值为对应类型的初始值(例如,0false)。对于引用类型,如 String,默认值为 null。因此,如果需要在反序列化后为 transient 属性赋予非默认值,需要自行在对象的构造函数或反序列化方法中处理。

  2. 版本兼容性:在使用 transient 关键字时,需要注意对象的版本兼容性。如果在对象的不同版本中添加或移除了 transient 属性,可能会导致反序列化时出现 InvalidClassException 异常。为了解决这个问题,可以使用 serialVersionUID 进行版本控制,确保序列化和反序列化的兼容性。

总结

transient 关键字允许我们在对象序列化过程中选择性地排除某些属性。这在保护敏感信息、优化性能和解决循环引用等方面非常有用。但在使用时需要小心,确保不会导致意外的行为。通过理解 transient 的工作原理和注意事项,您可以更好地控制对象的序列化过程。


http://www.ppmy.cn/news/1116502.html

相关文章

第七章 查找 三、折半查找(二分查找)

一、代码实现 此代码只能用于查找有序的顺序表 typedef struct {int *e;int len; }SSTable;int Search_Seq(SSTable st,int t){int i0,jst.len-1,mid;while (i<j){mid(ij)>>2;if (t>st.e[mid]){imid1;} else if (t<st.e[mid]){jmid-1;} else{return mid;}}ret…

FPGA-结合协议时序实现UART收发器(一):UART协议、架构规划、框图

FPGA-结合协议时序实现UART收发器&#xff08;一&#xff09;&#xff1a;UART协议、架构规划、框图 记录FPGA的UART学习笔记&#xff0c;以及一些细节处理&#xff0c;主要参考奇哥fpga学习资料。 本次UART主要采用计数器方法实现&#xff0c;实现uart的稳定性发送和接收功能…

windows flask服务卡死的问题

windows flask服务卡死的问题 最近的工作中&#xff0c;需要用python写一个flask服务&#xff0c;供C端调用&#xff0c;但是偶尔服务会卡住&#xff0c;只接收数据但不进行处理&#xff0c;不过CtrlC后又可以继续运行。 查看了网上的一些解决方法&#xff0c;但似乎都没有什…

功能基础篇4——Python数学计算,数字、分数、数学库、随机数、统计

数学 numbers 数字抽象基类&#xff0c;Python标准库 from numbers import Number, Real, Rational, Integralprint(isinstance(1.0, Number)) # True print(isinstance(1.0, Real)) # True print(isinstance(1.0, Rational)) # False print(isinstance(1.0, Integral)) …

计算机存储 和 零拷贝

1 读写速度 DDR4 50G/S > DDR3 10G/S > SSD 300M/S > HDD 100M/S 2 内存映射 物理内存 -> 物理内存地址 -> 虚拟内存地址-> MMU(Memory Management Unit) in CPU 3 内存使用 读共享&#xff0c;写复制&#xff0c;内存不够&#xff0c;虚拟磁盘 4 映射…

2023年12道超详细前端vue面试题,包含答案解析。你想要的都在这里!!!

欢迎参加2023年的Vue面试。以下是40道关于Vue的面试题&#xff0c;每道题附带有详细的答案和代码讲解。 请解释Vue.js是什么。它的核心功能是什么&#xff1f; Vue.js是一款流行的JavaScript前端框架&#xff0c;用于构建用户界面。它的核心功能是通过封装了核心库和插件生态系…

「聊设计模式」之中介者模式(Mediator)

&#x1f3c6;本文收录于《聊设计模式》专栏&#xff0c;专门攻坚指数级提升&#xff0c;助你一臂之力&#xff0c;带你早日登顶&#x1f680;&#xff0c;欢迎持续关注&&收藏&&订阅&#xff01; 前言 在软件开发过程中&#xff0c;我们通常会遇到一个问题&…

【SpringMVC】JSON注解全局异常处理机制

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Spring MVC》。&#x1f3…