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


    在这里插入图片描述

    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();
            }
        }
    }
    
    • 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

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

    注意事项

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

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

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

    总结

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

  • 相关阅读:
    python,满分,砝码称重【第十二届】【省赛】【研究生组】
    37.cuBLAS开发指南中文版--cuBLAS中的Level-2函数her()
    【组成原理-存储】存储器的相关知识
    Leetcode刷题笔记--Hot81--90
    SDUT F - 判断回文串
    金融科技,串联了互联网时代与数字时代
    XSS | 青训营笔记
    Spark安装、解压、配置环境变量、WordCount
    200.岛屿数量
    vulnstack-5
  • 原文地址:https://blog.csdn.net/qq_21484461/article/details/133049855