您的位置 首页 > 德语词汇

transient是什么意思?你真的搞懂

各位老铁们,大家好,今天由我来为大家分享transient是什么意思,以及你真的搞懂的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

我们的对象并不只是存在内存中,还需要传输网络,或者保存起来下次再加载出来用,所以需要Java序列化技术。

transient是什么意思?你真的搞懂

Java序列化技术正是将对象转变成一串由二进制字节组成的数组,可以通过将二进制数据保存到磁盘或者传输网络,磁盘或者网络接收者可以在对象的属类的模板上来反序列化类的对象,达到对象持久化的目的。

更多序列化请参考:《关于Java序列化你应该知道的一切》这篇文章。

简单来说就是,被transient修饰的变量不能被序列化。

具体来看下面的示例1

importjava.io.FileInputStream;\nimportjava.io.FileOutputStream;\nimportjava.io.ObjectInputStream;\nimportjava.io.ObjectOutputStream;\nimportjava.io.Serializable;\n\n/**\n*@author来源:Java技术栈\n*/\npublicclassTransientTest{\n\n\tpublicstaticvoidmain(String[]args)throwsException{\n\n\t\tUseruser=newUser();\n\t\tuser.setUsername("Java技术栈");\n\t\tuser.setId("javastack");\n\n\t\tSystem.out.println("\\n序列化之前");\n\t\tSystem.out.println("username:"+user.getUsername());\n\t\tSystem.out.println("id:"+user.getId());\n\n\t\tObjectOutputStreamos=newObjectOutputStream(newFileOutputStream("d:/user.txt"));\n\t\tos.writeObject(user);\n\t\tos.flush();\n\t\tos.close();\n\n\t\tObjectInputStreamis=newObjectInputStream(newFileInputStream("d:/user.txt"));\n\t\tuser=(User)is.readObject();\n\t\tis.close();\n\n\t\tSystem.out.println("\\n序列化之后");\n\t\tSystem.out.println("username:"+user.getUsername());\n\t\tSystem.out.println("id:"+user.getId());\n\n\t}\n}\n\n/**\n*@author来源:Java技术栈\n*/\nclassUserimplementsSerializable{\n\n\tprivatestaticfinallongserialVersionUID=1L;\n\n\tprivateStringusername;\n\tprivatetransientStringid;\n\n\tpublicStringgetUsername(){\n\t\treturnusername;\n\t}\n\n\tpublicvoidsetUsername(Stringusername){\n\t\tthis.username=username;\n\t}\n\n\tpublicStringgetId(){\n\t\treturnid;\n\t}\n\n\tpublicvoidsetId(Stringid){\n\t\tthis.id=id;\n\t}\n\n}\n\n\n

输出结果:

序列化之前\nusername:Java技术栈\nid:javastack\n\n序列化之后\nusername:Java技术栈\nid:null\n\n\n

示例1在id字段上加了transient关键字修饰,反序列化出来之后值为null,说明了被transient修饰的变量不能被序列化。

这个话题也是最近栈长的Java技术栈vip群里面讨论的,大家对这个知识点比较模糊,我就写了这篇文章测试总结一下。

如果你也想加入我们的Java技术栈vip群和各位大牛一起讨论技术,那点击这个链接了解加入吧。

那么,到底静态变量能被序列化吗?废话少说,先动手测试下吧!

importjava.io.FileInputStream;\nimportjava.io.FileOutputStream;\nimportjava.io.ObjectInputStream;\nimportjava.io.ObjectOutputStream;\nimportjava.io.Serializable;\n\n/**\n*@author来源:Java技术栈\n*/\npublicclassTransientStaticTest{\n\n\tpublicstaticvoidmain(String[]args)throwsException{\n\n\t\tUser2user=newUser2();\n\t\tUser2.username="Java技术栈1";\n\t\tuser.setId("javastack");\n\n\t\tSystem.out.println("\\n序列化之前");\n\t\tSystem.out.println("username:"+user.getUsername());\n\t\tSystem.out.println("id:"+user.getId());\n\n\t\tObjectOutputStreamos=newObjectOutputStream(newFileOutputStream("d:/user.txt"));\n\t\tos.writeObject(user);\n\t\tos.flush();\n\t\tos.close();\n\t\t\n\t\t//在反序列化出来之前,改变静态变量的值\n\t\tUser2.username="Java技术栈2";\n\n\t\tObjectInputStreamis=newObjectInputStream(newFileInputStream("d:/user.txt"));\n\t\tuser=(User2)is.readObject();\n\t\tis.close();\n\n\t\tSystem.out.println("\\n序列化之后");\n\t\tSystem.out.println("username:"+user.getUsername());\n\t\tSystem.out.println("id:"+user.getId());\n\n\t}\n}\n\n/**\n*@author来源:Java技术栈\n*/\nclassUser2implementsSerializable{\n\n\tprivatestaticfinallongserialVersionUID=1L;\n\n\tpublicstaticStringusername;\n\tprivatetransientStringid;\n\n\tpublicStringgetUsername(){\n\t\treturnusername;\n\t}\n\n\tpublicStringgetId(){\n\t\treturnid;\n\t}\n\n\tpublicvoidsetId(Stringid){\n\t\tthis.id=id;\n\t}\n\n}\n\n\n

输出结果:

序列化之前\nusername:Java技术栈1\nid:javastack\n\n序列化之后\nusername:Java技术栈2\nid:null\n\n\n

示例2把username改为了publicstatic,并在反序列化出来之前改变了静态变量的值,结果可以看出序列化之后的值并非序列化进去时的值。

由以上结果分析可知,静态变量不能被序列化,示例2读取出来的是username在JVM内存中存储的值。

importjava.io.Externalizable;\nimportjava.io.File;\nimportjava.io.FileInputStream;\nimportjava.io.FileOutputStream;\nimportjava.io.IOException;\nimportjava.io.ObjectInput;\nimportjava.io.ObjectInputStream;\nimportjava.io.ObjectOutput;\nimportjava.io.ObjectOutputStream;\n\n/**\n*@author来源:Java技术栈\n*/\npublicclassExternalizableTest{\n\n\tpublicstaticvoidmain(String[]args)throwsException{\n\n\t\tUser3user=newUser3();\n\t\tuser.setUsername("Java技术栈");\n\t\tuser.setId("javastack");\n\t\tObjectOutputobjectOutput=newObjectOutputStream(newFileOutputStream(newFile("javastack")));\n\t\tobjectOutput.writeObject(user);\n\n\t\tObjectInputobjectInput=newObjectInputStream(newFileInputStream(newFile("javastack")));\n\t\tuser=(User3)objectInput.readObject();\n\n\t\tSystem.out.println(user.getUsername());\n\t\tSystem.out.println(user.getId());\n\n\t\tobjectOutput.close();\n\t\tobjectInput.close();\n\t}\n\n}\n\n/**\n*@author来源:Java技术栈\n*/\nclassUser3implementsExternalizable{\n\n\tprivatestaticfinallongserialVersionUID=1L;\n\n\tpublicUser3(){\n\n\t}\n\n\tprivateStringusername;\n\tprivatetransientStringid;\n\n\tpublicStringgetUsername(){\n\t\treturnusername;\n\t}\n\n\tpublicvoidsetUsername(Stringusername){\n\t\tthis.username=username;\n\t}\n\n\tpublicStringgetId(){\n\t\treturnid;\n\t}\n\n\tpublicvoidsetId(Stringid){\n\t\tthis.id=id;\n\t}\n\n\t@Override\n\tpublicvoidwriteExternal(ObjectOutputobjectOutput)throwsIOException{\n\t\tobjectOutput.writeObject(id);\n\t}\n\n\t@Override\n\tpublicvoidreadExternal(ObjectInputobjectInput)throwsIOException,ClassNotFoundException{\n\t\tid=(String)objectInput.readObject();\n\t}\n\n}\n\n\n

输出结果:

null\njavastack\n\n\n

示例3的id被transient修改了,为什么还能序列化出来?那是因为User3实现了接口Externalizable,而不是Serializable。

在Java中有两种实现序列化的方式,Serializable和Externalizable,可能大部分人只知道Serializable而不知道Externalizable。

这两种序列化方式的区别是:实现了Serializable接口是自动序列化的,实现Externalizable则需要手动序列化,通过writeExternal和readExternal方法手动进行,这也是为什么上面的username为null的原因了。

1)transient修饰的变量不能被序列化;

2)transient只作用于实现Serializable接口;

3)transient只能用来修饰普通成员变量字段;

4)不管有没有transient修饰,静态变量都不能被序列化;

好了,栈长花了半天时间,终于整理完了。如果对你有帮助,那就转发分享一下吧!

另外,栈长已经整理了大量Java系列核心技术知识点文章,关注Java技术栈阅读吧。

OK,关于transient是什么意思和你真的搞懂的内容到此结束了,希望对大家有所帮助。

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023