浅析Serializable接口与transient关键字

发现很多Java基础知识不用的时候根本不知道,甚至有时候接触到了也会选择性忽略,之前在看JDK1.8部分源码的时候见到过transient,Google了一下也没去整理,加上阿里实习三面的时候被问到序列化,当时虽有一点印象,但是回答的并不好,这里查了一些网上资料,稍加整理尽量用最简单的语言说清楚这二者的所以然。

Java对象序列化

一般情况下,只有当JVM处于运行时,Java对象才可能存在,即这些对象的生命周期不会比JVM的生命周期更长。但是,对象序列化就能够帮助我们在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java序列化接口Serializable为处理对象序列化提供了一个标准机制,该接口简单易用。
除了在持久化对象时会用到对象序列化之外,当使用远程方法调用,或在网络中传递对象时,都会用到对象序列化。

Serializable接口

如果仅仅只是让某个类实现Serializable接口,而没有其它任何处理的话,则就是使用默认序列化机制。使用默认机制,在序列化对象时,不仅会序列化当前对象本身,还会对该对象引用的其它对象也进行序列化,同样地,这些其它对象引用的另外对象也将被序列化,以此类推。

transient关键字

如果在实际开发过程中使用了默认的Serializable,有些对象有一些敏感信息,你不希望在网络操作中被传输,或者被持久化到硬盘上,则可以在该变量前加上transient关键字即可。
之前并不知道transient关键字,直到看了JDK1.8中HashMap的源码之后才觉察到,HashMap的数据结构中很多关键的变量都是用transient来修饰,大家可以感受下:

1
2
3
4
5
6
7
8
9
10
11
transient Node<K,V>[] table;//HashMap中最重要也是最基本的数据结构之一,数组
/**
* Holds cached entrySet(). Note that AbstractMap fields are used
* for keySet() and values().
*/
transient Set<Map.Entry<K,V>> entrySet;
transient int size;//Map中k-v的数量
transient int modCount;//Map被修改次数

transient小结是建立在使用Serializable接口的基础上(如果自己实现了其他诸如Externalizable接口,则另当别论,暂时没接触也不写了):

  1. 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
  2. transient关键字只能修饰变量,而不能修饰方法和类。
  3. 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

参考

理解Java对象序列化
Java transient关键字使用小记

-EOF-