java关键字main解释_Java transient 关键字是干啥的

百度百科的解释:

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方法中执行,然后可以看到得到的结果为

50cd9dc7faffd7b0d3f7c79457959874.png

印证了上面所讲的“用transient关键字标记的成员变量不参与序列化过程”。

用二进制查看器打开这个文件也可以看到,数据中只有name1,没有name2。(请忽略乱码问题,这个不是重点哈。)

24f7f7fef421aa906f85ac75adfd8259.png

延伸:

在查看JDK源码的时候会发现很多地方都会加上transient关键字来修饰一些属性,那究竟是出于什么考虑才这么做呢?

我觉得,应该是为了节约磁盘空间,避免造成不必要的浪费吧。

以ArrayList中的 transient Object[] elementData 为例,这个成员变量的注释为:

944c6a230b5c17542409747ecc710ba6.png

翻译出来就是:

/ * *

*存储ArrayList元素的数组缓冲区。

* ArrayList的容量是这个数组缓冲区的长度。任何

*带有elementData的空ArrayList == DEFAULTCAPACITY_EMPTY_ELEMENTDATA

*当添加第一个元素时,将被扩展到DEFAULT_CAPACITY。

* /

这个缓冲区的容量实际上并不是ArrayList的容量,因为其实际上会预留一些空间,当空间不足时还会扩容,为减少浪费,因此在序列化时不会按照默认算法将这个成员变量写入磁盘。而是写了个writeObject方法,序列化时会调用这个方法将其持久化,在反序列化是,调用readObject,将其恢复出来。

这2个方法为:

2cb24c2605a793156394d894ad4155b6.png

895c5f048d066e61cf24fd8ff52581a7.png

参考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(),此时得到的结果是:

740261ea53acaf8b774b3ff9e8959001.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值