原文出处: 程序媛想事儿(@敏敏Alexia)html
哎,虽然本身最熟的是Java,但不少Java基础知识都不知道,好比transient关键字之前都没用到过,因此不知道它的做用是什么,今天作笔试题时发现有一题是关于这个的,因而花个时间整理下transient关键字的使用,涨下姿式~~~好了,废话很少说,下面开始:java
咱们都知道一个对象只要实现了Serilizable接口,这个对象就能够被序列化,java的这种序列化模式为开发者提供了不少便利,咱们能够没必要关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的全部属性和方法都会自动序列化。缓存
然而在实际开发过程当中,咱们经常会遇到这样的问题,这个类的有些属性须要序列化,而其余属性不须要被序列化,打个比方,若是一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不但愿在网络操做(主要涉及到序列化操做,本地序列化缓存也适用)中被传输,这些信息对应的变量就能够加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。安全
总之,java 的transient关键字为咱们提供了便利,你只须要实现Serilizable接口,将不须要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。网络
示例code以下:ide
1this 2spa 3.net 4code 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
|
输出为:
1 2 3 4 5 6 7 |
|
密码字段为null,说明反序列化时根本没有从文件中获取到信息。
1)一旦变量被transient修饰,变量将再也不是对象持久化的一部分,该变量内容在序列化后没法得到访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量若是是用户自定义类变量,则该类须要实现Serializable接口。
3)被transient关键字修饰的变量再也不能被序列化,一个静态变量不论是否被transient修饰,均不能被序列化。
第三点可能有些人很迷惑,由于发如今User类中的username字段前加上static关键字后,程序运行结果依然不变,即static类型的username也读出来为“Alexia”了,这不与第三点说的矛盾吗?其实是这样的:第三点确实没错(一个静态变量不论是否被transient修饰,均不能被序列化),反序列化后类中static型变量username的值为当前JVM中对应static变量的值,这个值是JVM中的不是反序列化得出的,不相信?好吧,下面我来证实:
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
|
运行结果为:
1 2 3 4 5 6 7 |
|
这说明反序列化后类中static型变量username的值为当前JVM中对应static变量的值,为修改后jmwang,而不是序列化时的值Alexia。
思考下面的例子:
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 42 43 44 45 46 47 48 |
|
content变量会被序列化吗?好吧,我把答案都输出来了,是的,运行结果就是:
1 |
|
这是为何呢,不是说类的变量被transient关键字修饰之后将不能序列化了吗?
咱们知道在Java中,对象的序列化能够经过实现两种接口来实现,若实现的是Serializable接口,则全部的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西能够自动序列化,须要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。所以第二个例子输出的是变量content初始化的内容,而不是null。