加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

transient关键字和序列化的关系

发布时间:2020-12-14 06:39:27 所属栏目:Java 来源:网络整理
导读:h3 id="1transient修饰实例变量"1.transient修饰实例变量 类序列化时,数组 or 集合类型均被保存为null; 类序列化时,基本类型也不保存其值; 反序列化时,基本类型会由JVM为其赋初值,比如int类型赋值为0。 说明:序列化时,即使实例变量的值并未保存,但

<h3 id="1transient修饰实例变量">1.transient修饰实例变量

  • 类序列化时,数组 or 集合类型均被保存为null;
  • 类序列化时,基本类型也不保存其值;
  • 反序列化时,基本类型会由JVM为其赋初值,比如int类型赋值为0。

说明:序列化时,即使实例变量的值并未保存,但是域还是存在的,只是域指向为空指针

<h3 id="2static变量">2.static变量

  • 序列化时,值会被保存。

  • 业务需要,不适合序列化一些字段值,比如银行密码;
  • 更重要的是:有时候默认的序列化方式不适合,所以这时候不采用默认的序列化,而是自己去定义序列化形式。
    • 比如hashMap中对元素的存储。java 7中hashMap元素的存储结构为 表 (table)+ 链(结点构成的链)的存储结构。其中根据hash(key)求的对应元素在table的索引,并将元素插入此索引处的链表。那么显然源码中对table使用了transient,故序列化时,table是不会存储值的,为什么这么设计?
    • 原因:不是不序列化,而是不采用默认的序列化。由于table中元素信息是我们存取关注的,而非table的结构,所以能合理的完成table中所有信息的存取是关键。鉴于table结构过于复杂(其中的链表结构为Entry 结点构成的链表),若采用默认的序列化方式,会将table的完整结构(包括各链表)镜像一份,如此以来带来一下弊端:
      • 需要消化大量时间遍历table结构
      • 占用较多的存储空间
      • 默认序列化对对象图做递归遍历当表过大时会发生堆栈溢出,所以避免使用默认的序列化方式。

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 list=new ArrayList<>();
transient HashSet 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,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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读