Java transient 關(guān)鍵字是干啥的
百度百科的解釋:
Java語言的關(guān)鍵字,變量修飾符,如果用transient聲明一個實例變量,當(dāng)對象存儲時,它的值不需要維持。換句話來說就是,用transient關(guān)鍵字標(biāo)記的成員變量不參與序列化過程。
作用:
Java的serialization提供了一種持久化對象實例的機制。當(dāng)持久化對象時,可能有一個特殊的對象數(shù)據(jù)成員,我們不想用serialization機制來保存它。為了在一個特定對象的一個域上關(guān)閉serialization,可以在這個域前加上關(guān)鍵字transient。當(dāng)一個對象被序列化的時候,transient型變量的值不包括在序列化的表示中,然而非transient型的變量是被包括進(jìn)去的。
編碼試驗加以證明:
1.自定義類(為了方便,我直接在main方法所在類中添加的一個靜態(tài)屬性類,或者叫成員類)
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="常規(guī)屬性",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方法中執(zhí)行,然后可以看到得到的結(jié)果為

印證了上面所講的“用transient關(guān)鍵字標(biāo)記的成員變量不參與序列化過程”。
用二進(jìn)制查看器打開這個文件也可以看到,數(shù)據(jù)中只有name1,沒有name2。(請忽略亂碼問題,這個不是重點哈。)

延伸:
在查看JDK源碼的時候會發(fā)現(xiàn)很多地方都會加上transient關(guān)鍵字來修飾一些屬性,那究竟是出于什么考慮才這么做呢?
我覺得,應(yīng)該是為了節(jié)約磁盤空間,避免造成不必要的浪費吧。
以ArrayList中的 transient Object[] elementData 為例,這個成員變量的注釋為:

翻譯出來就是:
/ * * *存儲ArrayList元素的數(shù)組緩沖區(qū)。 * ArrayList的容量是這個數(shù)組緩沖區(qū)的長度。任何 *帶有elementData的空ArrayList == DEFAULTCAPACITY_EMPTY_ELEMENTDATA *當(dāng)添加第一個元素時,將被擴(kuò)展到DEFAULT_CAPACITY。 * /
這個緩沖區(qū)的容量實際上并不是ArrayList的容量,因為其實際上會預(yù)留一些空間,當(dāng)空間不足時還會擴(kuò)容,為減少浪費,因此在序列化時不會按照默認(rèn)算法將這個成員變量寫入磁盤。而是寫了個writeObject方法,序列化時會調(diào)用這個方法將其持久化,在反序列化是,調(diào)用readObject,將其恢復(fù)出來。
這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方法中執(zhí)行testTransient(),此時得到的結(jié)果是:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
BigDecimal的toString()、toPlainString()和toEngineeringString()區(qū)
使用BigDecimal進(jìn)行打印的時候,經(jīng)常會對BigDecimal提供的三個toString方法感到好奇,以下整理3個toString方法的區(qū)別及用法,需要的朋友可以參考下2023-08-08
如何使用Spring Validation優(yōu)雅地校驗參數(shù)
這篇文章主要介紹了如何使用Spring Validation優(yōu)雅地校驗參數(shù),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
基于visualvm監(jiān)控類實現(xiàn)過程詳解
這篇文章主要介紹了基于visualvm監(jiān)控類實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09
java json字符串轉(zhuǎn)JSONObject和JSONArray以及取值的實例
這篇文章主要介紹了java json字符串轉(zhuǎn)JSONObject和JSONArray以及取值的實例的相關(guān)資料,需要的朋友可以參考下2017-05-05
解決mybatis三表連接查詢數(shù)據(jù)重復(fù)的問題
這篇文章主要介紹了解決mybatis三表連接查詢數(shù)據(jù)重復(fù)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01

