1.transient修饰实例变量
- 类序列化时,数组 or 集合类型均被保存为null;
- 类序列化时,基本类型也不保存其值;
- 反序列化时,基本类型会由JVM为其赋初值,比如int类型赋值为0。
说明:序列化时,即使实例变量的值并未保存,但是域还是存在的,只是域指向为空指针
2.static变量
- 序列化时,值会被保存。
3.transient存在意义:
- 业务需要,不适合序列化一些字段值,比如银行密码;
- 更重要的是:有时候默认的序列化方式不适合,所以这时候不采用默认的序列化,而是自己去定义序列化形式。
- 比如hashMap中对元素的存储。java 7中hashMap元素的存储结构为 表 (table)+ 链(结点构成的链)的存储结构。其中根据hash(key)求的对应元素在table的索引,并将元素插入此索引处的链表。那么显然源码中对table使用了transient,故序列化时,table是不会存储值的,为什么这么设计?
- 原因:不是不序列化,而是不采用默认的序列化。由于table中元素信息是我们存取关注的,而非table的结构,所以能合理的完成table中所有信息的存取是关键。鉴于table结构过于复杂(其中的链表结构为Entry 结点构成的链表),若采用默认的序列化方式,会将table的完整结构(包括各链表)镜像一份,如此以来带来一下弊端:
- 需要消化大量时间遍历table结构
- 占用较多的存储空间
- 默认序列化对对象图做递归遍历当表过大时会发生堆栈溢出,所以避免使用默认的序列化方式。
4.代码测试:
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
class Test implements Serializable{
private static final long serialVersionUID = 99689012974701994L;
transient int num1;
static int num2;
int num3;
transient int[] arrays={1,2,3};
transient ArrayList<Integer> list=new ArrayList<>();
transient HashSet<Integer> set=new HashSet<>();
transient HashMap<Integer,Integer> map=new HashMap<>();
Test(int n1,int n2,int n3){
this.num1=n1;
this.num2=n2;
this.num3=n3;
list.add(1);
set.add(2);
map.put(1,2);
}
private void get(){
System.out.println("1111");
}
}
public class Main {
public static void main(String[] args) {
//Scanner scanner = new Scanner(System.in);在线笔试
//序列化
try{
Test test=new Test(1,2,3);
ObjectOutputStream o=new ObjectOutputStream(new FileOutputStream("/Users/caoxiaohong/Downloads/test.txt"));
o.writeObject(test);
o.close();
}catch (Exception e){
e.printStackTrace();
}
//反序列化
try{
ObjectInputStream in=new ObjectInputStream(new FileInputStream("/Users/caoxiaohong/Downloads/test.txt"));
Test readIn=(Test)in.readObject();
System.out.println("Test.num1="+readIn.num1);
System.out.println("Test.num2="+readIn.num2);
System.out.println("Test.num3="+readIn.num3);
if(readIn.arrays==null){
System.out.println("Test.arrays is null");
}else{
System.out.println("Test.arrays.length="+readIn.arrays.length);
}
if(readIn.list==null){
System.out.println("Test.list is null");
}else{
System.out.println("Test.list.size()="+readIn.list.size());
}
if(readIn.set==null){
System.out.println("Test.set is null");
}else{
System.out.println("Test.set.size()="+readIn.set.size());
}
if(readIn.map==null){
System.out.println("Test.map is null");
}else{
System.out.println("Test.map.size()="+readIn.map.size());
}
}catch (Exception e){
e.printStackTrace();
}
}
}
输出结果:
Test.num1=0
Test.num2=2
Test.num3=3
Test.arrays is null
Test.list is null
Test.set is null
Test.map is null
Process finished with exit code 0