transient的⽤途及使⽤⽅法
1,⽤途
  我们知道,当⼀个对象实现了Serilizable接⼝,这个对象就可以被序列化,我们不关⼼其内在的原理,只需要了解这个类实现了Serilizable接⼝,这个类的所有属性和⽅法都会⾃动序列化。⽽在开发过程中,我们可能要求:当对象被序列化时(写⼊字节序列到⽬标⽂件)时,有些属性需要序列化,⽽其他属性不需要被序列化,打个⽐⽅,如果⼀个⽤户有⼀些敏感信息(如密码,银⾏卡号等),为了安全起见,不希望在⽹络操作(主要涉及到序列化操作,本地序列化缓存也适⽤)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的⽣命周期仅存于调⽤者的内存中⽽不会写到磁盘⾥持久化。
 所以,transient的⽤途在于:阻⽌实例中那些⽤此关键字声明的变量持久化;当对象被反序列化时(从源⽂件读取字节序列进⾏重构),这样的实例变量值不会被持久化和恢复。例如,当反序列化对象——数据流(例如,⽂件)可能不存在时,原因是你的对象中存在类型为java.io.InputStream的变量,序列化时这些变量引⽤的输⼊流⽆法被打开。
2,使⽤⽅法
序列化的时候,将不需要序列化的属性前添加关键字transient即可。
⽰例:
<span ><code><span >package</span> newDay.day13;
<span >import</span> java.io.FileInputStream;
<span >import</span> java.io.FileOutputStream;
<span >import</span> java.io.ObjectInputStream;
<span >import</span> java.io.ObjectOutputStream;
<span >import</span> java.io.Serializable;
class UserInfo implements Serializable {
<span >private</span> <span >static</span> <span >final</span> <span color:#000088">private</span> String name;
<span >private</span> <span >transient</span> String p
sw;
<span >public</span> <span >UserInfo</span>(String name, String psw) {
<span >this</span>.name = name;
<span >this</span>.psw = psw;
}
<span >public</span> String <span >toString</span>() {
<span >return</span> <span >"name="</span> + name + <span >", psw="</span> + psw;      }
}
<span >public</span> <span >class</span> <span >TestTransient</span> {
<span >public</span> <span >static</span> <span >void</span> <span color:#000088">new</span> UserInfo(<span >"张三"</span>, <span >"123456"        System.out.println(userInfo);
<span >try</span> {
try catch的使用方法<span >// 序列化,被设置为transient的属性没有被序列化  </span>
ObjectOutputStream o = <span >new</span> ObjectOutputStream(<span >new</span> FileOutputStream(<sp            o.writeObject(userInfo);
o.close();
} <span >catch</span> (Exception e) {
<span >// TODO: handle exception  </span>
e.printStackTrace();
}
<span >try</span> {
<span >// 重新读取内容  </span>
ObjectInputStream in = <span >new</span> ObjectInputStream(<span >new</span> FileInputStream(<span s            UserInfo readUserInfo = (UserInfo) in.readObject();
<span >//读取后psw的内容为null  </span>
System.out.String());
} <span >catch</span> (Exception e) {
<span >// TODO: handle exception  </span>
e.printStackTrace();
}
}
}</code></span>
运⾏结果:
<span ><code>name=张三, psw=<span >123456</span>
name=张三, psw=null</code></span>
  密码字段为null,说明被标记为transient的属性在对象被序列化的时候不会被保存。
使⽤⼩结:
  1,⼀旦变量被transient修饰,变量将不再是对象持久化的⼀部分,该变量内容在序列化后⽆法获得访问。
  2,transient关键字只能修饰变量,⽽不能修饰⽅法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是⽤户⾃定义
类变量,则该类需要实现Serializable接⼝。
  3,被transient关键字修饰的变量不再能被序列化,⼀个静态变量不管是否被transient修饰,均不能被序列化。
  对于第三点,加上static之后,依然能把姓名输出。这是因为:反序列化后类中static型变量name的值为当前JVM中对应static变量的
值,这个值是JVM中的不是反序列化得出的。下例可说明,其值时JVM中得到的⽽不是反序列化得到的:
<span ><code><span >package</span> newDay.day13;
<span >import</span> java.io.FileInputStream;
<span >import</span> java.io.FileOutputStream;
<span >import</span> java.io.ObjectInputStream;
<span >import</span> java.io.ObjectOutputStream;
<span >import</span> java.io.Serializable;
class UserInfo implements Serializable {
<span >private</span> <span >static</span> <span >final</span> <span color:#000088">private</span> <span >static</span> String name;
<span >private</span> <span >transient</span> String psw;
<span >public</span> <span >UserInfo</span>(String name, String psw) {
<span >this</span>.name = name;
<span >this</span>.psw = psw;
}
<span >public</span> <span >static</span> String <span >getName</span>() {
<span >return</span> name;
}
<span >public</span> <span >static</span> <span >void</span> <span color:#000088">public</span> String <span >getPsw</span>() {
<span >return</span> psw;
}
<span >public</span> <span >void</span> <span >setPsw</span>(String psw) {
<span >this</span>.psw = psw;
}
<span >public</span> String <span >toString</span>() {
<span >return</span> <span >"name="</span> + name + <span >", psw="</span> + psw;      }
}
<span >public</span> <span >class</span> <span >TestTransient</span> {
<span >public</span> <span >static</span> <span >void</span> <span color:#000088">new</span> UserInfo(<span >"张三"</span>, <span >"123456"        System.out.println(userInfo);
<span >try</span> {
<span >// 序列化,被设置为transient的属性没有被序列化  </span>
ObjectOutputStream o = <span >new</span> ObjectOutputStream(<span >new</span> FileOutputStream(<sp            o.writeObject(userInfo);
o.close();
} <span >catch</span> (Exception e) {
<span >// TODO: handle exception  </span>
e.printStackTrace();
}
<span >try</span> {
<span >//在反序列化之前改变name的值</span>
userInfo.setName(<span >"hello"</span>);
<span >// 重新读取内容  </span>
ObjectInputStream in = <span >new</span> ObjectInputStream(<span >new</span> FileInputStream(<span s            UserInfo readUserInfo = (UserInfo) in.readObject();
UserInfo readUserInfo = (UserInfo) in.readObject();
<span >//读取后psw的内容为null  </span>
System.out.String());
} <span >catch</span> (Exception e) {
<span >// TODO: handle exception  </span>
e.printStackTrace();
}
}
}</code></span>
运⾏结果:
<span ><code>name=张三, psw=<span >123456</span>
name=hello, psw=null</code></span>
这说明反序列化后类中static型变量name的值为当前JVM中对应static变量的值,为修改后hello,⽽不是序列化时的值“张三”

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。