transient关键字

简介: transient关键字

transient 关键字


1,使用transient关键字向java虚拟机表明,transient变量不是对象的持久状态的一部分。


为了方便理解直接上例子


import lombok.Data;
import java.io.Serializable;
@Data
public class Employee implements Serializable {
    private static final long serialVersionUID = 2624368016355021172L;
    private String           firstName;
    private String           lastName;
    /**
     * 使用transient关键字向java虚拟机表明,
     * transient变量不是对象的持久状态的一部分。
     */
    private transient String confidentialInfo;
    // Getter and Setter
}


序列化


import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class TransSerializationTest {
    public static void main(String[] args) {
        try {
            Employee emp = new Employee();
            emp.setFirstName("Chen");
            emp.setLastName("Shuaishuai");
            emp.setConfidentialInfo("password");
            System.out.println("Read before Serialization:");
            System.out.println("firstName: " + emp.getFirstName());
            System.out.println("lastName: " + emp.getLastName());
            System.out.println("confidentialInfo: " + emp.getConfidentialInfo());
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("chenss.txt"));
            //Serialize the object
            oos.writeObject(emp);
            oos.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}


反序列化


import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class TransDeSerializationTest {
    public static void main(String[] args) {
        try {
            ObjectInputStream ooi = new ObjectInputStream(new FileInputStream("chenss.txt"));
            //Read the object back
            Employee readEmpInfo = (Employee) ooi.readObject();
            System.out.println("Read From Serialization:");
            System.out.println("firstName: " + readEmpInfo.getFirstName());
            System.out.println("lastName: " + readEmpInfo.getLastName());
            System.out.println("confidentialInfo: " + readEmpInfo.getConfidentialInfo());
            ooi.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}


运行序列化与反序列化后会有如下的输出:


Read From Serialization:
firstName: Chen
lastName: Shuaishuai
confidentialInfo: null


发现添加了关键字transient关键字后对象的相对应的属性是没有序列化的。也就是说当我们不需要对应的属性进行序列化的时候就可以使用该关键字。


2,final关键字修饰的属性添加transient关键字


那接下来我们看看在使用final关键后会有什么样的变化。在属性中添加一个String类型的属性和Logger的属性,先上代码:


import lombok.Data;
import org.apache.log4j.Logger;
import org.junit.Test;
import java.io.Serializable;
@Data
public class Employee implements Serializable {
    private static final long serialVersionUID = 2624368016355021172L;
    private String           firstName;
    private String           lastName;
    //final field 1
    public final transient String confidentialInfo = "password";
    //final field 2
    private final transient Logger logger = Logger.getLogger("demo");
    //Getter and Setter
}


序列化


import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class TransSerializationTest {
    public static void main(String[] args) {
        try {
            Employee emp = new Employee();
            emp.setFirstName("Chen");
            emp.setLastName("Shuaishuai");
            System.out.println("Read before Serialization:");
            System.out.println("firstName: " + emp.getFirstName());
            System.out.println("lastName: " + emp.getLastName());
            System.out.println("confidentialInfo: " + emp.getConfidentialInfo());
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("chenss.txt"));
            //Serialize the object
            oos.writeObject(emp);
            oos.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}


反序列化:


import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class TransDeSerializationTest {
    public static void main(String[] args) {
        try {
            ObjectInputStream ooi = new ObjectInputStream(new FileInputStream("chenss.txt"));
            //Read the object back
            Employee readEmpInfo = (Employee) ooi.readObject();
            System.out.println("Read From Serialization:");
            System.out.println("firstName: " + readEmpInfo.getFirstName());
            System.out.println("lastName: " + readEmpInfo.getLastName());
            System.out.println("confidentialInfo: " + readEmpInfo.getConfidentialInfo());
            System.out.println("logger: " + readEmpInfo.getLogger());
            ooi.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}


序列化与反序列化后的输出:


Read From Serialization:
firstName: Chen
lastName: Shuaishuai
confidentialInfo: password
logger: null



从输出结果中我们可以看到:添加final关键字的属性中 confidentialInfo 进行了序列化,而logger没有进行序列化。


很奇怪。我们已将confidentialInfo标记为transient;字段仍然被序列化了。而对于类似的声明,logger却没有被序列化。为什么?


原因是,无论何时将任何final字段/引用计算为“常量表达式”,JVM都会对其进行序列化,忽略transient关键字的存在。


在上面的例子中,值password是一个常量表达式,logger demo的实例是引用。因此,根据规则,confidentialInfo被持久化,而logger没有被持久化。


您是否在想,如果我从两个字段中删除transient呢?那么,实现可序列化引用的字段将保持不变。因此,如果在上面的代码中删除transient,String(实现Serializable)将被持久化;而Logger(不实现Serializable)将不会被持久化,并且将会抛出异常java.io.NotSerializableException。


如果希望持久保存不可序列化字段的状态,那么可以使用readObject()和writeObject()方法。writeObject()/readObject()通常在内部链接到序列化/反序列化机制中,因此会自动调用。


了解更多:点击


原文:https://www.jianshu.com/p/2911e5946d5c


这篇文章几乎全来自于原文,这里学习了记录一下。感谢作者


说明serialVersionUID


serialVersionUID是Serializable类的通用版本标识符。反序列化使用这个数字来确保加载的类与序列化的对象完全对应。如果没有找到匹配,则抛出InvalidClassException。|।1。始终将它作为一个字段包含,例如:"private static final long serialVersionUID = 7526472295622776147L: "即使在类的第一个版本中也要包含这个字段,以提醒它的重要性。不要在未来的版本中更改此字段的值,除非你有意地对类进行更改,使其与旧的序列化对象不兼容。如有需要,请遵循上述指导方针


相关文章
|
存储 安全 虚拟化
深入解析:Docker的架构与组件
【8月更文挑战第27天】
515 5
|
12月前
|
存储 网络协议 大数据
一文读懂RDMA: Remote Direct Memory Access(远程直接内存访问)
该文档详细介绍了RDMA(远程直接内存访问)技术的基本原理、主要特点及其编程接口。RDMA通过硬件直接在应用程序间搬移数据,绕过操作系统协议栈,显著提升网络通信效率,尤其适用于高性能计算和大数据处理等场景。文档还提供了RDMA编程接口的概述及示例代码,帮助开发者更好地理解和应用这一技术。
|
存储 缓存 算法
高并发架构设计三大利器:缓存、限流和降级
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。
339 1
|
安全 区块链 数据安全/隐私保护
隐私计算实训营 第1期-第2讲 隐私计算开源如何助力数据要素流通
本文探讨了数据要素流通中的三个关键主体——数据提供方、数据消费方和数据平台方的忧虑。数据提供方关注商业秘密、个人隐私、数据使用控制及安全合规;数据消费方则担忧数据授权链和合规使用;数据平台方旨在解决双方疑虑,提供主体审核、授权链路审核、合规评审等服务。技术可信是关键,涉及隐私计算(数据可用不可见)、数据空间与区块链技术(数据可控可计量)以及数据匿名化(数据可算不可识)等。
|
存储 运维 前端开发
淘宝 NPM 镜像站切换新域名啦
用CNPM/淘宝源的开发者们请注意,淘宝NPM 镜像站喊你切换新域名啦。新的Web 站点:https://npmmirror.com,Registry Endpoint:https://registry.npmmirror.com。随着新的域名已经正式启用,老 http://npm.taobao.org 和 http://registry.npm.taobao.org 域名将于 2022 年 05 月 31 日零时起停止服务。(望周知,求转发)
14996 1
|
存储 C语言
[C语言/PTA] 单链表结点删除
[C语言/PTA] 单链表结点删除
238 0
|
前端开发
css如何实现快速居中?
简单来说快速居中,就是给它的父级设置display: flex;属性,自身设置margin: auto;的属性
105 0
|
安全 iOS开发 Windows
iOS 逆向编程(三)实操越狱详细流程(一)
iOS 逆向编程(三)实操越狱详细流程
341 0
|
编解码 前端开发 UED
什么是响应式网站?响应式网站建设解决方案
响应式网站完全采用全网3合1建站方式,实现一个后台多种终端兼容展示,所有访问终端统一访问地址,响应式网站建设的解决方案对于多终端的兼容展示是重点,接下来小编为你详细分享什么是响应式网站建设以及实用的解决方案,一起来看看吧。
381 0
什么是响应式网站?响应式网站建设解决方案
view.setTag()的正确使用姿势
开发中,我们经常要进行数据的传递,会使用到view.setTag()和view.getTag()方法,主要用在view的点击事件中,可以让数据跟着view走,这种方法很方便。一般情况下给view设置一个tag就够用了,某些情况下我们需要给一个view设置多个tag,在需要的时候再分别取出来,这就需要用到view.setTag()的一个重载方法view.setTag(int key,final Object Tag)了。