十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
Java中transient关键字的作用是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
成都创新互联公司是一家以网站建设、网页设计、品牌设计、软件运维、seo优化排名、小程序App开发等移动开发为一体互联网公司。已累计为成都木托盘等众行业中小客户提供优质的互联网建站和软件开发服务。Java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。
作用:
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。
编码试验加以证明:
1.自定义类(为了方便,我直接在main方法所在类中添加的一个静态属性类,或者叫成员类)
public static class TransientTest implements Serializable{ private static final long serialVersionUID = 233858934995755239L; private String name1; private transient String name2; public TransientTest(String name1,String name2){ this.name1 = name1; this.name2 = name2; } public String toString(){ return String.format("TransientTest.toString(): name1=%s,name2=%s", name1,name2); } }
2.写一个测试方法
public static void testTransient(){ String name1="常规属性",name2="transient修饰的属性"; TransientTest test = new TransientTest(name1, name2); System.out.println("序列化前:"+test.toString()); ObjectOutputStream outStream; ObjectInputStream inStream; String filePath = "D:/test/object/TransientTest.obj"; try { outStream = new ObjectOutputStream(new FileOutputStream(filePath)); outStream.writeObject(test); inStream = new ObjectInputStream(new FileInputStream(filePath)); TransientTest readObject = (TransientTest)inStream.readObject(); System.out.println("序列化后:"+readObject.toString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
3.在main方法中执行,然后可以看到得到的结果为
印证了上面所讲的“用transient关键字标记的成员变量不参与序列化过程”。
用二进制查看器打开这个文件也可以看到,数据中只有name1,没有name2。(请忽略乱码问题,这个不是重点哈。)
延伸:
在查看JDK源码的时候会发现很多地方都会加上transient关键字来修饰一些属性,那究竟是出于什么考虑才这么做呢?
我觉得,应该是为了节约磁盘空间,避免造成不必要的浪费吧。
以ArrayList中的 transient Object[] elementData 为例,这个成员变量的注释为:
翻译出来就是:
/ * * *存储ArrayList元素的数组缓冲区。 * ArrayList的容量是这个数组缓冲区的长度。任何 *带有elementData的空ArrayList == DEFAULTCAPACITY_EMPTY_ELEMENTDATA *当添加第一个元素时,将被扩展到DEFAULT_CAPACITY。 * /
这个缓冲区的容量实际上并不是ArrayList的容量,因为其实际上会预留一些空间,当空间不足时还会扩容,为减少浪费,因此在序列化时不会按照默认算法将这个成员变量写入磁盘。而是写了个writeObject方法,序列化时会调用这个方法将其持久化,在反序列化是,调用readObject,将其恢复出来。
这2个方法为:
参考ArrayList,在上面的TransientTest中添加2个方法,见代码:
public static class TransientTest implements Serializable{ private static final long serialVersionUID = 233858934995755239L; private String name1; private transient String name2; public TransientTest(String name1,String name2){ this.name1 = name1; this.name2 = name2; } public String toString(){ return String.format("TransientTest.toString(): name1=%s,name2=%s", name1,name2); } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { s.defaultWriteObject(); s.writeObject(name2); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); name2=String.valueOf(s.readObject()); } }
然后在main方法中执行testTransient(),此时得到的结果是:
关于Java中transient关键字的作用是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联网站建设公司行业资讯频道了解更多相关知识。
另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。