最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA transient 關(guān)鍵字作用詳解

 更新時間:2025年11月28日 11:44:05   作者:猩火燎猿  
Java的transient關(guān)鍵字用于修飾成員變量,使其不參與序列化過程,通過自定義序列化方法,可以手動控制transient變量的序列化行為,本文給大家介紹JAVA transient 關(guān)鍵字作用,感興趣的朋友跟隨小編一起看看吧

一、transient關(guān)鍵字作用

  • 作用transient 用于修飾成員變量,表示該變量不參與序列化過程。
  • 場景:當對象被序列化(如寫入磁盤、通過網(wǎng)絡(luò)傳輸)時,transient 修飾的變量不會被保存到序列化流中。

二、原理詳解

Java 的對象序列化機制(如 ObjectOutputStream)會將對象的所有非靜態(tài)、非瞬態(tài)(transient)成員變量序列化到字節(jié)流中。
transient 關(guān)鍵字告訴 JVM:該變量是臨時的,不需要序列化。

反序列化時,transient 變量會被賦予默認值(如 int 為 0,引用類型為 null)。

三、典型使用場景

  • 敏感信息
  • 如密碼、身份證號等,不希望被序列化存儲或傳輸。
  • 臨時計算結(jié)果
  • 如緩存、臨時狀態(tài),不需要持久化。
  • 不可序列化對象
  • 某些成員變量類型沒有實現(xiàn) Serializable,可以用 transient 跳過。

四、代碼示例

import java.io.*;
class User implements Serializable {
    private String username;
    private transient String password; // 不序列化
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}
public class TransientDemo {
    public static void main(String[] args) throws Exception {
        User user = new User("Tom", "123456");
        // 序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.obj"));
        oos.writeObject(user);
        oos.close();
        // 反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.obj"));
        User user2 = (User) ois.readObject();
        ois.close();
        System.out.println(user2.username); // Tom
        System.out.println(user2.password); // null
    }
}

五、注意事項

  1. 只修飾變量,不能修飾方法、類、局部變量。
  2. 靜態(tài)變量不參與序列化,即使沒有 transient 修飾,也不會被序列化。
  3. 自定義序列化:如果實現(xiàn)了 writeObject 和 readObject,可以手動控制 transient 變量的序列化行為。

六、與 static 的區(qū)別

  • static 修飾的變量屬于類,不屬于對象,不參與序列化。
  • transient 修飾的變量屬于對象,但被標記為不參與序列化。

七、面試常見問題

  • transient 變量能否被序列化?
    • 默認不會被序列化,但可以通過自定義序列化方法手動序列化。
  • 序列化后 transient 變量的值是什么?
    • 反序列化后為默認值(int 為 0,引用類型為 null)。
  • transient 和 static 有什么區(qū)別?
    • static 不參與序列化,transient 標記為不參與序列化。
  • 為什么要用 transient?
    • 保護敏感信息、優(yōu)化存儲、避免不可序列化成員導(dǎo)致序列化失敗。

八、補充:自定義序列化 transient 變量

如果你想讓 transient 變量也能序列化,可以自定義 writeObject/readObject:

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    oos.writeObject(password); // 手動序列化
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    password = (String) ois.readObject(); // 手動反序列化
}

九、總結(jié)表

特性說明
作用標記變量不參與序列化
默認值反序列化后為默認值
修飾對象只能修飾成員變量
典型場景敏感信息/臨時變量/不可序列化對象
可否自定義可通過 writeObject/readObject 手動處理

十. 序列化機制與 transient 的底層原理

Java 的序列化機制通過 ObjectOutputStream 和 ObjectInputStream 實現(xiàn)。序列化時,JVM 會遍歷對象的所有字段,只有滿足以下條件的字段才會被序列化:

  • 非 static
  • 非 transient
  • 類型實現(xiàn)了 Serializable 接口

transient 的本質(zhì)
JVM 在序列化對象時,會判斷字段是否被 transient 修飾,如果是,則跳過該字段,不寫入字節(jié)流。

十一. 常見誤區(qū)與陷阱

誤區(qū)一:transient 修飾的變量絕對不會被序列化

實際情況:如果你自定義了 writeObject/readObject 方法,可以手動序列化 transient 字段。

誤區(qū)二:transient 只能用于敏感信息

實際情況:transient 還可以用于臨時計算、緩存、不可序列化成員等場景。

誤區(qū)三:static transient 有意義

實際情況:static 字段本身就不會被序列化,transient 修飾 static 字段沒有任何作用。

十二. 進階應(yīng)用:自定義序列化 transient 字段

有時你希望 transient 字段能被序列化,但不想默認序列化,可以自定義序列化方法:

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject(); // 序列化非transient字段
    oos.writeObject(this.transientField); // 手動序列化transient字段
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject(); // 反序列化非transient字段
    this.transientField = (Type) ois.readObject(); // 手動反序列化transient字段
}

十三. 實際應(yīng)用場景擴展

  • 分布式系統(tǒng):如 RPC 框架、緩存對象,常用 transient 跳過網(wǎng)絡(luò)不需要傳輸?shù)谋镜貭顟B(tài)。
  • 安全與合規(guī):如日志審計、敏感數(shù)據(jù)脫敏,防止敏感信息被持久化或泄露。
  • 性能優(yōu)化:減少序列化內(nèi)容,提升網(wǎng)絡(luò)傳輸和磁盤存儲效率。
  • 不可序列化對象:如數(shù)據(jù)庫連接、線程池等,這些對象不能序列化,否則會報錯。

十四. 面試陷阱代碼分析

陷阱一:

class Test implements Serializable {
    private transient int a = 10;
    private int b = 20;
}

如果序列化后反序列化,a 的值是多少?
答案: 0(int 默認值),b 是 20。

陷阱二:

class Test implements Serializable {
    private static transient int a = 10;
}

序列化后反序列化,a 的值是多少?
答案: 10(static 字段不會被序列化,值取決于類加載時的靜態(tài)初始化)

十五. transient 與其他關(guān)鍵字的對比

關(guān)鍵字作用是否序列化
transient標記不序列化成員變量
static類變量,不屬于對象
final常量,只能賦值一次

十六. 進階:transient 與可變對象

如果 transient 修飾的是引用類型變量(如 List),反序列化后會變?yōu)?null。
如果需要恢復(fù)數(shù)據(jù),可以在 readObject 方法里初始化或重建。

十七. 典型面試題總結(jié)

  • transient 修飾的變量序列化后會是什么?
    • 對于基本類型,是默認值;對于引用類型,是 null。
  • transient 可以修飾 static 嗎?
    • 可以,但沒有實際意義。
  • transient 變量能否通過自定義序列化保存?
    • 可以,需實現(xiàn) writeObject/readObject 方法。
  • 為什么要用 transient?
    • 安全、性能、避免不可序列化成員導(dǎo)致異常。

十八. 補充:序列化版本號與 transient

  • serialVersionUID 是 static final 字段,不參與序列化。
  • 如果類結(jié)構(gòu)變化,反序列化可能失敗,transient 字段不會影響序列化兼容性。

十九.transient與序列化機制的深層關(guān)系

1 序列化的過程

  • Java 的序列化機制會遞歸地序列化對象的每個非 static、非 transient 字段。
  • 如果字段類型本身不可序列化(沒有實現(xiàn) Serializable),但未被 transient 修飾,序列化會拋出 NotSerializableException。

2 反序列化過程

  • 反序列化時,transient 字段不會從流中恢復(fù),直接賦予默認值。
  • 如果你希望反序列化后給 transient 字段賦初值,可以用如下方式:
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    this.transientField = ...; // 這里可以初始化
}

二十.transient相關(guān)的安全問題

1 敏感數(shù)據(jù)泄露

  • 如果敏感字段未被 transient 修飾,序列化后可能被寫入磁盤或通過網(wǎng)絡(luò)傳輸,造成安全隱患。
  • 建議:對所有敏感信息(如密碼、token、身份證號等)都加上 transient。

2 反序列化漏洞

  • transient 字段不會參與序列化和反序列化,但如果你在 readObject 里對 transient 字段做了不安全的初始化,也可能被攻擊者利用(如反序列化 gadget 鏈)。

二十一. 性能優(yōu)化相關(guān)

  • 對于大對象,如果某些字段無需持久化,使用 transient 可以顯著減少序列化數(shù)據(jù)體積,提高網(wǎng)絡(luò)傳輸和存儲性能。
  • 在高性能緩存、分布式對象同步等場景,合理使用 transient 能避免不必要的負擔。

二十二. 在主流框架中的應(yīng)用

1 Spring

  • Spring 的 Bean、Session 等對象有時會被序列化傳遞,常用 transient 跳過如數(shù)據(jù)庫連接、線程池、日志等不可序列化資源。

2 Hibernate/JPA

  • 實體類中有些字段(如 logger、臨時緩存)會加 transient,避免持久化和序列化。

3 分布式緩存/消息隊列

  • Redis、Kafka、RocketMQ 等都會用到對象序列化,transient 可以跳過本地狀態(tài)和敏感字段。

二十三. 進階:transient 與自定義序列化框架

  • Java原生序列化只認 transient,第三方序列化(如 Jackson、Fastjson、Kryo、Protobuf)不一定認 transient。
  • 比如 Jackson 需要配合 @JsonIgnore 注解,而不是 transient。
  • 工程建議:如果需要跨多種序列化框架,建議同時用 transient 和注解(如 @JsonIgnore)雙重標記。

二十四. 面試高頻“陷阱”與實戰(zhàn)建議

1 面試陷阱代碼

class Person implements Serializable {
    private transient int age = 18;
    private String name = "Tom";
}

序列化后反序列化,age 是多少?
答案:0(int 默認值),不是 18。

2 實戰(zhàn)建議

  • 對所有不可序列化或敏感字段,都加 transient。
  • 如果需要恢復(fù) transient 字段值,建議在 readObject 里初始化。
  • 對于跨多種序列化框架的項目,建議加上相應(yīng)的注解。

二十五. 結(jié)合實際業(yè)務(wù)場景舉例

1 緩存對象

class CacheObject implements Serializable {
    private String data;
    private transient long lastAccessTime; // 僅本地有效
}

2 日志字段

class ServiceBean implements Serializable {
    private String id;
    private transient Logger log = LoggerFactory.getLogger(ServiceBean.class);
}

3 線程池、數(shù)據(jù)庫連接等資源

class Job implements Serializable {
    private transient ExecutorService threadPool;
    private transient Connection dbConn;
}

二十六. 小結(jié)

  • transient 是 Java 原生序列化機制的關(guān)鍵字,主要用于跳過不需要序列化的字段。
  • 適用于敏感信息、臨時狀態(tài)、不可序列化成員、性能優(yōu)化等多種場景。
  • 結(jié)合自定義序列化,可以靈活控制序列化和反序列化行為。
  • 在分布式、緩存、框架開發(fā)等實際工程中非常常見。
  • transient 用于控制序列化行為,保護敏感信息,優(yōu)化性能,處理不可序列化成員。
  • 反序列化后 transient 字段為默認值。
  • 可通過自定義序列化方法手動保存/恢復(fù) transient 字段。

到此這篇關(guān)于JAVA transient 關(guān)鍵字詳解的文章就介紹到這了,更多相關(guān)java transient 關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring基礎(chǔ)篇之初識DI和AOP

    Spring基礎(chǔ)篇之初識DI和AOP

    這篇文章主要為大家詳細介紹了Spring基礎(chǔ)篇之初識DI和AOP,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Spring Boot高級教程之Spring Boot連接MySql數(shù)據(jù)庫

    Spring Boot高級教程之Spring Boot連接MySql數(shù)據(jù)庫

    這篇文章主要為大家詳細介紹了Spring Boot高級教程之Spring Boot連接MySql數(shù)據(jù)庫,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Spring?Security6.3.x的使用指南與注意事項

    Spring?Security6.3.x的使用指南與注意事項

    Spring?Security?6.3.1基于現(xiàn)代化架構(gòu),提供簡潔配置、增強默認安全性和OAuth2.1/OIDC支持,采用LambdaDSL和組件化設(shè)計,涵蓋用戶認證、方法級權(quán)限控制及資源服務(wù)器配置,強調(diào)PasswordEncoder、HTTPS、CSRF保護等最佳實踐,下面是Spring?Security?6.3.1?的使用指南,一起學(xué)習吧
    2025-08-08
  • java使用Hex編碼解碼實現(xiàn)Aes加密解密功能示例

    java使用Hex編碼解碼實現(xiàn)Aes加密解密功能示例

    這篇文章主要介紹了java使用Hex編碼解碼實現(xiàn)Aes加密解密功能,結(jié)合完整實例形式分析了Aes加密解密功能的定義與使用方法,需要的朋友可以參考下
    2017-01-01
  • Redis六大數(shù)據(jù)類型使用方法詳解

    Redis六大數(shù)據(jù)類型使用方法詳解

    這篇文章主要介紹了Redis六大數(shù)據(jù)類型使用方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-12-12
  • Java使用validation攔截非法提交的數(shù)據(jù)的方法實現(xiàn)

    Java使用validation攔截非法提交的數(shù)據(jù)的方法實現(xiàn)

    這篇文章主要介紹了Java使用validation攔截非法提交的數(shù)據(jù),包含依賴引入、實體類注解配置、控制器@Valid/@Validated使用規(guī)范,具有一定的參考價值,感興趣的可以了解一下
    2025-07-07
  • Springboot視圖解析器ViewResolver使用實例

    Springboot視圖解析器ViewResolver使用實例

    這篇文章主要介紹了Springboot視圖解析器ViewResolver使用實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-04-04
  • MyBatis中常用的SQL語句詳解

    MyBatis中常用的SQL語句詳解

    MyBatis是一種優(yōu)秀的持久層框架,它支持定制化SQL、存儲過程以及高級映射,本文介紹了MyBatis中常用的SQL語句,包括基本查詢、多條件查詢、關(guān)聯(lián)查詢、分頁查詢、插入、更新、刪除等,并結(jié)合MyBatis的特性進行了說明
    2025-03-03
  • Java操作Jenkins操作憑證(Credential)信息方式

    Java操作Jenkins操作憑證(Credential)信息方式

    這篇文章主要介紹了Java操作Jenkins操作憑證(Credential)信息方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • Java 數(shù)組(Array)存儲數(shù)據(jù)的“排排坐”(最新推薦)

    Java 數(shù)組(Array)存儲數(shù)據(jù)的“排排坐”(最新推薦)

    這篇文章主要介紹了Java 數(shù)組(Array)存儲數(shù)據(jù)的“排排坐”(最新推薦),本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2025-05-05

最新評論

永清县| 黄陵县| 牙克石市| 黄浦区| 青岛市| 潞西市| 苗栗县| 宁强县| 会泽县| 陆良县| 陇西县| 江油市| 洪雅县| 五莲县| 泊头市| 德阳市| 九台市| 彰化市| 沙坪坝区| 宁津县| 沂源县| 桃园市| 柘城县| 普洱| 库车县| 舒城县| 西青区| 黄冈市| 策勒县| 甘南县| 弥勒县| 和顺县| 通城县| 遵义市| 虎林市| 始兴县| 基隆市| 伊金霍洛旗| 翼城县| 泸溪县| 泸州市|