Java中的关键字 transient详解编程语言
在讨论transient之前,有必要先搞清楚Java中序列化的含义;
Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,也可用于网络传输,一般当我们使用缓存cache(内存空间不够有可能会本地存储到硬盘)或远程调用rpc(网络传输)的时候,经常需要让我们的实体类实现Serializable接口,目的就是为了让其可序列化。
当然,序列化后的最终目的是为了反序列化,恢复成原先的Java对象,要不然序列化后干嘛呢,所以序列化后的字节序列都是可以恢复成Java对象的,这个过程就是反序列化。
关于transient关键字Java中transient关键字的作用,简单地说,就是让某些被修饰的成员属性变量不被序列化,这一看好像很好理解,就是不被序列化,那么什么情况下,一个对象的某些字段不需要被序列化呢?如果有如下情况,可以考虑使用关键字transient修饰:
1、类中的字段值可以根据其它字段推导出来,如一个长方形类有三个属性:长度、宽度、面积(示例而已,一般不会这样设计),那么在序列化的时候,面积这个属性就没必要被序列化了;
2、其它,看具体业务需求吧,哪些字段不想被序列化;
PS,记得之前看HashMap源码的时候,发现有个字段是用transient修饰的,我觉得还是有道理的,确实没必要对这个modCount字段进行序列化,因为没有意义,modCount主要用于判断HashMap是否被修改(像put、remove操作的时候,modCount都会自增),对于这种变量,一开始可以为任何值,0当然也是可以(new出来、反序列化出来、或者克隆clone出来的时候都是为0的),没必要持久化其值。
/** * The number of times this HashMap has been structurally modified * Structural modifications are those that change the number of mappings in * the HashMap or otherwise modify its internal structure (e.g., * rehash). This field is used to make iterators on Collection-views of * the HashMap fail-fast. (See ConcurrentModificationException). transient int modCount;
最后,为什么要不被序列化呢,主要是为了节省存储空间,其它的感觉没啥好处,可能还有坏处(有些字段可能需要重新计算,初始化什么的),总的来说,利大于弊。
仅仅是示例,具体使用请根据实际情况:
package tmp; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class Rectangle implements Serializable{ /** private static final long serialVersionUID = 1710022455003682613L; private Integer width; private Integer height; private transient Integer area;
public class TransientExample{ public static void main(String args[]) throws Exception { Rectangle rectangle = new Rectangle(3,4); System.out.println("1.原始对象/n"+rectangle); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("rectangle")); // 往流写入对象 o.writeObject(rectangle); o.close(); // 从流读取对象 ObjectInputStream in = new ObjectInputStream(new FileInputStream("rectangle")); Rectangle rectangle1 = (Rectangle)in.readObject(); System.out.println("2.反序列化后的对象/n"+rectangle1); rectangle1.setArea(); System.out.println("3.恢复成原始对象/n"+rectangle1); in.close(); }
结果打印(达到目的,节省存储空间,成功恢复成原始对象):
1.原始对象width : 3
height : 4
area : 12
2.反序列化后的对象
width : 3
height : 4
area : null
3.恢复成原始对象
width : 3
height : 4
area : 12
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/16364.html
cjava相关文章
- java输出值取后两位小数,Java输出结果保留两位小数
- java中如何获取当前系统时间[通俗易懂]
- Java 9 中的 GC 调优基础详解编程语言
- java lisi乱序、排序详解编程语言
- Java反射工具类详解编程语言
- Java 内存区域分配和垃圾回收(GC)机制详解编程语言
- Java中各种集合的线程安全性!!!详解编程语言
- java基础Haep(堆)和Stack(栈)区别详解编程语言
- java线程池的作用详解编程语言
- JAVA网络爬虫抓数据jar包Jsoup的简易用法详解编程语言
- java实现验证码详解编程语言
- java上传图片文件和回显详解编程语言
- java中Vector和ArrayList的详解编程语言
- java判断集合list是为空详解编程语言
- Java Web(五) JSP详解(四大作用域九大内置对象等)编程语言
- Java泛型的PECS原则详解编程语言
- Java中的多线程你只要看这一篇就够了详解编程语言
- Java多线程(三):synchronized关键字详解编程语言
- java 输出一对双引号详解编程语言
- #随笔之java匿名内部类详解编程语言
- Java多线程知识点详解编程语言
- Java多线程16:线程组详解编程语言
- 数据库Java查询Oracle数据库:一种快捷、可靠的解决方案(java查询oracle)
- Java 离开 Oracle,新的旅程即将开始(java没有Oracle)