当前位置:首页 > 科技  > 软件

面试官:Transient关键字修饰的变量当真不可序列化?

来源: 责编: 时间:2024-06-27 17:13:00 70观看
导读一、写在开头在这篇文章中记录一下之前自己面试时学到的东西,是关于transient关键字的,当时面试官问我IO的相关问题,基本上全答出来了,关于如何不序列化对象中某个字段时,我果断的选择了static和transient,但面试官紧接着问

一、写在开头

在这篇文章中记录一下之前自己面试时学到的东西,是关于transient关键字的,当时面试官问我IO的相关问题,基本上全答出来了,关于如何不序列化对象中某个字段时,我果断的选择了static和transient,但面试官紧接着问了我:“transient关键字修饰的变量当真不可序列化吗?”,这个问题直接给我整不确定了,因为以当时的知识储备,这个问题确实不知道,最终虚心的向这位面试官请教,他告诉了我答案。Cfo28资讯网——每日最新资讯28at.com

虽然那场面试我还是通过了,但是我没去,哈哈!不过还是挺感谢那个耐心的面试官的,随口的一个问题,其实大部分面试官是不会负责给你解答的。Cfo28资讯网——每日最新资讯28at.com

二、案例测试

今天,我们就花一点时间,来把这个问题梳理一遍。我们先写一个测试类,去看一下static和transient关键字修饰的字段,在序列化过程中的表现:Cfo28资讯网——每日最新资讯28at.com

public class Test {    public static void main(String[] args) throws IOException {        //初始化对象信息        Person person = new Person();        person.setName("JavaBuild");        person.setAge(30);        System.out.println(person.getName()+" "+person.getAge());        //序列化过程        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("E://person.txt"));) {            objectOutputStream.writeObject(person);        } catch (IOException e) {            e.printStackTrace();        }        person.par1 = "序列化后静态字段";        //反序列化过程        try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E://person.txt"));) {            Person p = (Person) objectInputStream.readObject();            System.out.println(p);        } catch (IOException | ClassNotFoundException e) {            e.printStackTrace();        }    }}class Person implements Serializable{    private static final long serialVersionUID = 8711922740433840551L;    private String name;    private int age;    public static String par1 = "静态字段";    transient String par2 = "临时字段";    transient int high = 175;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "Person{" +                "name='" + name + '/'' +                ", age=" + age +                ", par1=" + par1 +                ", high=" + high +                ", par2='" + par2 + '/'' +                '}';    }}

输出:Cfo28资讯网——每日最新资讯28at.com

JavaBuild 30Person{name='JavaBuild', age=30, par1=序列化后静态字段, high=0, par2='null'}

通过打印结果我们可以看到,static修饰的字段,并没有参与序列化,读取到了后面修改的值;transient关键字修饰的字段也没参与,而且在反序列化过程中,会被重置为默认值,例如基本数据类型为 0,引用类型为 null。至于原因我们在这里不展开了,上一篇文章里已经提到,大家可以去看看。Cfo28资讯网——每日最新资讯28at.com

三、直入主题

我们再回过头来看看起初的问题:transient 修饰的字段真的不能被序列化?至少通过Serializable接口标示的序列化方式里,transient字段时不可被序列化的,因为在序列化过程中调用的ObjectStreamClass对象,里面有个方法为getDefaultSerialFields(),已经明确的标记出了transient修饰符不可被序列化!Cfo28资讯网——每日最新资讯28at.com

图片图片Cfo28资讯网——每日最新资讯28at.com

那我们怎么办呢?Cfo28资讯网——每日最新资讯28at.com

Externalizable接口:

其实呀,除了 Serializable 之外,Java 还提供了一个序列化接口 Externalizable,它是Serializable的子接口,使用 Externalizable 进行反序列化的时候,会调用被序列化类的无参构造方法去创建一个新的对象,然后再将被保存对象的字段值复制过去;实现Externalizable接口时,必须重写其中的writeExternal() 和 readExternal()方法,我们通过这两个方法进行序列化的设计与读取。Cfo28资讯网——每日最新资讯28at.com

图片图片Cfo28资讯网——每日最新资讯28at.com

适应场景: 因为Externalizable接口拥有着更高的序列化控制能力,所以在序列化过程中,我们需要对一些敏感信息进行加密处理时,它的作用就会体现啦。Cfo28资讯网——每日最新资讯28at.com

我们使用这个接口进行序列化尝试,并且使用transient关键字修饰字段,看一下结果:Cfo28资讯网——每日最新资讯28at.com

public class Test implements Externalizable {    private transient String text = "我可以被序列化!!!";    public static void main(String[] args) throws Exception {        Test test = new Test();        //序列化        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("E://transient.txt"));        out.writeObject(test);        //反序列化        ObjectInputStream in = new ObjectInputStream(new FileInputStream("E://transient.txt"));        test = (Test)in.readObject();        System.out.println(test.text);        //关闭流        out.close();        in.close();    }    @Override    public void writeExternal(ObjectOutput out) throws IOException {        out.writeObject(text);    }    @Override    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {        text = (String) in.readObject();    }}

输出:Cfo28资讯网——每日最新资讯28at.com

我可以被序列化!!!

数据成功被序列化到txt文件中,并成功的反序列化读取到程序中了!即便text被transient修饰着!Cfo28资讯网——每日最新资讯28at.com

四、总结

通过上面的学习,我们知道了在Java的序列化中有 Serializable、Externalizable这两个接口,前者没有任何方法,只是一个标识,而后者作为子类,提供了必须重写的方法,用以自定义序列化设计。此外,transient 关键字只能修饰字段,而不能修饰方法和类,需要注意。Cfo28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-96974-0.html面试官:Transient关键字修饰的变量当真不可序列化?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 萌兽医馆三年敏捷 BI 建设之旅,携手观远数据推进数字化革新

下一篇: 我们一起聊聊如何通过流式渲染提升用户体验?

标签:
  • 热门焦点
  • 直屏旗舰来了 iQOO 12和K70 Pro同台竞技

    直屏旗舰来了 iQOO 12和K70 Pro同台竞技

    旗舰机基本上使用的都是双曲面屏幕,这就让很多喜欢直屏的爱好者在苦等一款直屏旗舰,这次,你们等到了。据博主数码闲聊站带来的最新爆料称,Redmi下代旗舰K70 Pro和iQOO 12两款手
  • 6月iOS设备性能榜:M2稳居榜首 A系列只能等一手3nm来救

    6月iOS设备性能榜:M2稳居榜首 A系列只能等一手3nm来救

    没有新品发布,自然iOS设备性能榜的上榜设备就没有什么更替,仅仅只有跑分变化而产生的排名变动,毕竟苹果新品的发布节奏就是这样的,一年下来也就几个移动端新品,不会像安卓厂商,一
  • 把LangChain跑起来的三个方法

    把LangChain跑起来的三个方法

    使用LangChain开发LLM应用时,需要机器进行GLM部署,好多同学第一步就被劝退了,那么如何绕过这个步骤先学习LLM模型的应用,对Langchain进行快速上手?本片讲解3个把LangChain跑起来
  • WebRTC.Net库开发进阶,教你实现屏幕共享和多路复用!

    WebRTC.Net库开发进阶,教你实现屏幕共享和多路复用!

    WebRTC.Net库:让你的应用更亲民友好,实现视频通话无痛接入! 除了基本用法外,还有一些进阶用法可以更好地利用该库。自定义 STUN/TURN 服务器配置WebRTC.Net 默认使用 Google 的
  • Python异步IO编程的进程/线程通信实现

    Python异步IO编程的进程/线程通信实现

    这篇文章再讲3种方式,同时讲4中进程间通信的方式一、 Python 中线程间通信的实现方式共享变量共享变量是多个线程可以共同访问的变量。在Python中,可以使用threading模块中的L
  • 2天涨粉255万,又一赛道在抖音爆火

    2天涨粉255万,又一赛道在抖音爆火

    来源:运营研究社作者 | 张知白编辑 | 杨佩汶设计 | 晏谈梦洁这个暑期,旅游赛道彻底火了:有的「地方」火了——贵州村超旅游收入 1 个月超过 12 亿;有的「博主」火了&m
  • 品牌洞察丨服务本地,美团直播成效几何?

    品牌洞察丨服务本地,美团直播成效几何?

    来源:17PR7月11日,美团App首页推荐位出现“美团直播”的固定入口。在直播聚合页面,外卖“神枪手”直播间、美团旅行直播间、美团买菜直播间等均已上线,同时
  • 东方甄选单飞:有些鸟注定是关不住的

    东方甄选单飞:有些鸟注定是关不住的

    作者:彭宽鸿来源:华尔街科技眼‍‍‍‍‍‍‍‍‍‍东方甄选创始人俞敏洪带队的“7天甘肃行”直播活动已在近日顺利收官。成立后一
  • 机构称Q2全球智能手机出货量同比下滑11% 苹果份额依旧第2

    机构称Q2全球智能手机出货量同比下滑11% 苹果份额依旧第2

    7月20日消息,据外媒报道,研究机构的报告显示,由于需求下滑,今年二季度全球智能手机的出货量,同比下滑了11%,三星、苹果等主要厂商的销量,较去年同期均有下
Top