Java transient症結字應用小記。本站提示廣大學習愛好者:(Java transient症結字應用小記)文章只能為提供參考,不一定能成為您想要的結果。以下是Java transient症結字應用小記正文
哎,固然本身最熟的是Java,但許多Java基本常識都不曉得,好比transient症結字之前都沒用到過,所以不曉得它的感化是甚麼,明天做口試題時發明有一題是關於這個的,因而花個時光整頓下transient症結字的應用,漲下姿態~~~好了,空話不多說,上面開端:
1. transient的感化及應用辦法
我們都曉得一個對象只需完成了Serilizable接口,這個對象便可以被序列化,java的這類序列化形式為開辟者供給了許多方便,我們可以不用關系詳細序列化的進程,只需這個類完成了Serilizable接口,這個類的一切屬性和辦法都邑主動序列化。
但是在現實開辟進程中,我們經常會碰到如許的成績,這個類的有些屬性須要序列化,而其他屬性不須要被序列化,打個比喻,假如一個用戶有一些敏感信息(如暗碼,銀行卡號等),為了平安起見,不願望在收集操作(重要觸及到序列化操作,當地序列化緩存也實用)中被傳輸,這些信息對應的變量便可以加上transient症結字。換句話說,這個字段的性命周期僅存於挪用者的內存中而不會寫到磁盤裡耐久化。
總之,java 的transient症結字為我們供給了方便,你只須要完成Serilizable接口,將不須要序列化的屬性前添加症結字transient,序列化對象的時刻,這個屬性就不會序列化到指定的目標地中。
示例code以下:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * @description 應用transient症結字不序列化某個變量 * 留意讀取的時刻,讀取數據的次序必定要和寄存數據的次序堅持分歧 * * @author Alexia * @date 2013-10-15 */ public class TransientTest { public static void main(String[] args) { User user = new User(); user.setUsername("Alexia"); user.setPasswd("123456"); System.out.println("read before Serializable: "); System.out.println("username: " + user.getUsername()); System.err.println("password: " + user.getPasswd()); try { ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream("C:/user.txt")); os.writeObject(user); // 將User對象寫進文件 os.flush(); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { ObjectInputStream is = new ObjectInputStream(new FileInputStream( "C:/user.txt")); user = (User) is.readObject(); // 從流中讀取User的數據 is.close(); System.out.println("\nread after Serializable: "); System.out.println("username: " + user.getUsername()); System.err.println("password: " + user.getPasswd()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } class User implements Serializable { private static final long serialVersionUID = 8294180014912103005L; private String username; private transient String passwd; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } }
輸入為:
read before Serializable: username: Alexia password: 123456 read after Serializable: username: Alexia password: null
暗碼字段為null,解釋反序列化時基本沒有從文件中獲得到信息。
2. transient應用小結
1)一旦變量被transient潤飾,變量將不再是對象耐久化的一部門,該變量內容在序列化後沒法取得拜訪。
2)transient症結字只能潤飾變量,而不克不及潤飾辦法和類。留意,當地變量是不克不及被transient症結字潤飾的。變量假如是用戶自界說類變量,則該類須要完成Serializable接口。
3)被transient症結字潤飾的變量不再能被序列化,一個靜態變量不論能否被transient潤飾,均不克不及被序列化。
第三點能夠有些人很困惑,由於發明在User類中的username字段前加上static症結字後,法式運轉成果仍然不變,即static類型的username也讀出來為“Alexia”了,這不與第三點說的抵觸嗎?現實上是如許的:第三點確切沒錯(一個靜態變量不論能否被transient潤飾,均不克不及被序列化),反序列化後類中static型變量username的值為以後JVM中對應static變量的值,這個值是JVM中的不是反序列化得出的,不信任?好吧,上面我來證實:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * @description 應用transient症結字不序列化某個變量 * 留意讀取的時刻,讀取數據的次序必定要和寄存數據的次序堅持分歧 * * @author Alexia * @date 2013-10-15 */ public class TransientTest { public static void main(String[] args) { User user = new User(); user.setUsername("Alexia"); user.setPasswd("123456"); System.out.println("read before Serializable: "); System.out.println("username: " + user.getUsername()); System.err.println("password: " + user.getPasswd()); try { ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream("C:/user.txt")); os.writeObject(user); // 將User對象寫進文件 os.flush(); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { // 在反序列化之前轉變username的值 User.username = "jmwang"; ObjectInputStream is = new ObjectInputStream(new FileInputStream( "C:/user.txt")); user = (User) is.readObject(); // 從流中讀取User的數據 is.close(); System.out.println("\nread after Serializable: "); System.out.println("username: " + user.getUsername()); System.err.println("password: " + user.getPasswd()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } class User implements Serializable { private static final long serialVersionUID = 8294180014912103005L; public static String username; private transient String passwd; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } }
運轉成果為:
read before Serializable: username: Alexia password: 123456 read after Serializable: username: jmwang password: null
這解釋反序列化後類中static型變量username的值為以後JVM中對應static變量的值,為修正後jmwang,而不是序列化時的值Alexia。
3. transient應用細節——被transient症結字潤飾的變量真的不克不及被序列化嗎?
思慮上面的例子:
import java.io.Externalizable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; /** * @descripiton Externalizable接口的應用 * * @author Alexia * @date 2013-10-15 * */ public class ExternalizableTest implements Externalizable { private transient String content = "是的,我將會被序列化,不論我能否被transient症結字潤飾"; @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(content); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { content = (String) in.readObject(); } public static void main(String[] args) throws Exception { ExternalizableTest et = new ExternalizableTest(); ObjectOutput out = new ObjectOutputStream(new FileOutputStream( new File("test"))); out.writeObject(et); ObjectInput in = new ObjectInputStream(new FileInputStream(new File( "test"))); et = (ExternalizableTest) in.readObject(); System.out.println(et.content); out.close(); in.close(); } }
content變量會被序列化嗎?好吧,我把謎底都輸入來了,是的,運轉成果就是:
是的,我將會被序列化,不論我能否被transient症結字潤飾
這是為何呢,不是說類的變量被transient症結字潤飾今後將不克不及序列化了嗎?
我們曉得在Java中,對象的序列化可以經由過程完成兩種接口來完成,若完成的是Serializable接口,則一切的序列化將會主動停止,若完成的是Externalizable接口,則沒有任何器械可以主動序列化,須要在writeExternal辦法中停止手工指定所要序列化的變量,這與能否被transient潤飾有關。是以第二個例子輸入的是變量content初始化的內容,而不是null。
作者:Alexia(minmin)
假如您願望與我交換互動,迎接微博互粉
原文銜接:http://www.cnblogs.com/lanxuezaipiao/p/3369962.html
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。