先解释一下吧,我最初看到这个关键字的时候,是好早的时候,还在学校的时候,在书籍上面看到的,但是由于最近这个看源码看到比较多,好像很多地方都有出现过,于是就打算看下到底是个怎么回事.于是就有了这篇文章.
transient 简介
java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。
作用 : Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。
在缓存机制中、IO(读写文件)、网络传输的过程中,我们对一些文件、字符、图像的传输是没有办法整体传输的,那么我们这个时候会将这些对象转换成字节进行数据的传输,这个过程就是序列化的过程。但是,打个比方我们在进行信息传递的过程中有一些敏感信息例如密码是不能够进行传输的,这时候我们就需要在密码属性前面添加transient关键字,使密码属性跳出对象序列化的范围中,所以在一定程度上保证了该信息的安全。
是不是有人会问 什么是序列化啊? 于是我去百度了下:
序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
transient 简单使用
package com.yang.keyword.ktransient; import java.io.*; /** * @Author: Mu_Yi * @Date: 2019/10/8 23:03 * @Version 1.0 * @qq: 1411091515 */ public class KeyWordTransient implements Serializable { private static final long serialVersionUID = 1L; private String name = "Gavin"; private int age = 18; private transient String pwd = "HelloWrold"; @Override public String toString() { return "KeyWordTransient{" + "name='" + name + '\'' + ", age=" + age + ", pwd='" + pwd + '\'' + '}'; } public static void main(String[] args) throws IOException { KeyWordTransient keyWordTransient = new KeyWordTransient(); System.out.println(keyWordTransient.toString()); FileOutputStream fos = null; ObjectOutputStream oos = null; try { // 序列化写入到文件中 fos = new FileOutputStream("D:\\Java_DaiMa\\idea_github_self\\thread-learn-case\\basic-grammar-learn\\transient.txt"); oos = new ObjectOutputStream(fos); // KeyWordTransient keyWordTransient1 = (KeyWordTransient) oos.readObject(); // System.out.println(keyWordTransient1.toString()); oos.writeObject(keyWordTransient); }catch (Exception e){ e.printStackTrace(); } finally { if(fos != null){ fos.close(); } if(oos != null){ oos.close(); } } FileInputStream ffis = null; ObjectInputStream oois = null; try { // 读取出序列化的值 ffis = new FileInputStream("D:\\Java_DaiMa\\idea_github_self\\thread-learn-case\\basic-grammar-learn\\transient.txt"); oois = new ObjectInputStream(ffis); KeyWordTransient k2 = (KeyWordTransient) oois.readObject(); System.out.println(k2.toString()); }catch (Exception e){ e.printStackTrace(); }finally { if(ffis != null){ ffis.close(); } if(oois != null){ oois.close(); } } } }
运行的效果 ; 可以看到pwd这个字段的值是没有被序列化出来的.
使用二:
使用 Externalizable 接口来操作,可以从结果中看出区别;
如果你的 pwd初始化的不是null;是123的话 ,那么最后序列化出来的值也会是123
package com.yang.keyword.ktransient; import java.io.*; /** * @Author: Mu_Yi * @Date: 2019/10/8 23:28 * @Version 1.0 * @qq: 1411091515 */ public class KeyWordTransientTwoCase implements Externalizable { private String name = "Gavin Name"; private int age = 29; private String pwd = null; 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; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "KeyWordTransientTwoCase{" + "name='" + name + '\'' + ", age=" + age + ", pwd='" + pwd + '\'' + '}'; } @Override public void writeExternal(ObjectOutput out) throws IOException { System.out.println("WriteExternal method is called."); out.writeObject(name); out.writeObject(age); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("ReadExternal method is called."); this.name = (String) in.readObject(); this.age = (int) in.readObject(); } public static void main(String[] args) throws Exception { KeyWordTransientTwoCase keyWordTransientTwoCase = new KeyWordTransientTwoCase(); keyWordTransientTwoCase.setName("GavinName"); keyWordTransientTwoCase.setAge(23); keyWordTransientTwoCase.setPwd("GavinPwd"); System.out.println(keyWordTransientTwoCase.toString()); FileOutputStream fos = null; ObjectOutputStream oos = null; try{ fos = new FileOutputStream("D:\\Java_DaiMa\\idea_github_self\\thread-learn-case\\basic-grammar-learn\\transienttwo.txt"); oos = new ObjectOutputStream(fos); oos.writeObject(keyWordTransientTwoCase); }catch (Exception e){ e.printStackTrace(); } finally { if(fos != null){ fos.close(); } if(oos != null){ oos.close(); } } FileInputStream ffis = null; ObjectInputStream fois = null; try { ffis = new FileInputStream("D:\\Java_DaiMa\\idea_github_self\\thread-learn-case\\basic-grammar-learn\\transienttwo.txt"); fois = new ObjectInputStream(ffis); KeyWordTransientTwoCase k2 = (KeyWordTransientTwoCase) fois.readObject(); System.out.println(k2.toString()); }catch (Exception e){ e.printStackTrace(); } finally { if(ffis != null){ ffis.close(); } if(fois != null){ fois.close(); } } } }
未被序列化的情况 ; 这里从结果中可以看出,我加了 关键字的修饰,但是pwd的值;还是被序列化出来了。这是因为
Externalizable ;重写了其方法导致。package com.yang.keyword.ktransient; import java.io.*; /** * @Author: Mu_Yi * @Date: 2019/10/8 23:44 * @Version 1.0 * @qq: 1411091515 */ public class KeyWordTransientThreeCase implements Externalizable { private String name = "Gavin Name"; private int age = 29; private String pwd = "GavinPwd"; 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; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "KeyWordTransientThreeCase{" + "name='" + name + '\'' + ", age=" + age + ", pwd='" + pwd + '\'' + '}'; } @Override public void writeExternal(ObjectOutput out) throws IOException { System.out.println("WriteExternal method is call."); out.writeObject(name); out.writeObject(age); out.writeObject(pwd); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("ReadExternal method is call."); this.name = (String) in.readObject(); this.age = (int) in.readObject(); this.pwd = (String) in.readObject(); } public static void main(String[] args) throws Exception { KeyWordTransientThreeCase keyWordTransientThreeCase = new KeyWordTransientThreeCase(); keyWordTransientThreeCase.setName("GavinName"); keyWordTransientThreeCase.setAge(23); keyWordTransientThreeCase.setPwd("GavinPwd"); System.out.println(keyWordTransientThreeCase.toString()); FileOutputStream fos = null; ObjectOutputStream oos = null; try{ fos = new FileOutputStream("D:\\Java_DaiMa\\idea_github_self\\thread-learn-case\\basic-grammar-learn\\transientthree.txt"); oos = new ObjectOutputStream(fos); oos.writeObject(keyWordTransientThreeCase); }catch (Exception e){ e.printStackTrace(); } finally { if(fos != null){ fos.close(); } if(oos != null){ oos.close(); } } FileInputStream ffis = null; ObjectInputStream fois = null; try { ffis = new FileInputStream("D:\\Java_DaiMa\\idea_github_self\\thread-learn-case\\basic-grammar-learn\\transientthree.txt"); fois = new ObjectInputStream(ffis); KeyWordTransientThreeCase k2 = (KeyWordTransientThreeCase) fois.readObject(); System.out.println(k2.toString()); }catch (Exception e){ e.printStackTrace(); } finally { if(ffis != null){ ffis.close(); } if(fois != null){ fois.close(); } } } }