Java中的泛型底層是怎樣的

Java 泛型深入底層原理解析:類型擦除與橋方法的真相

一、Java中的偽泛型

Java 從 JDK 1.5 引入泛型之后,大大提升了代碼的類型安全性可讀性。但泛型的底層實現并不像 C++ 的模板機制那樣是“真正的泛型”,Java 的泛型是偽泛型,在編譯后會進行類型擦除,這帶來了很多容易忽略的陷阱。

這篇文章將主要介紹Java 泛型是如何通過擦除實現,泛型在編譯期與運行期發生了什么,為什么會出現橋方法,以及通過反射獲取泛型信息


二、泛型基本語法

public class Box<T> {private T value;public void set(T value) { this.value = value; }public T get() { return value; }
}

我們可以通過如下方式使用它:

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
// 編譯器知道 stringBox 中只能放 String

看似“類型安全”,但實際運行時情況并不是這樣。因為運行時,由于類型擦除機制,泛型的類型信息被移除,導致實際運行中并不能真正限制類型,看下面這段代碼,因為編譯時期進行了類型擦除,因此反射時jvm并不知道list中只允許添加String

List<String> list = new ArrayList<>();
list.add("hello");// 通過反射繞過泛型限制
Method addMethod = list.getClass().getMethod("add", Object.class);
addMethod.invoke(list, 123);  // 添加了一個 IntegerSystem.out.println(list);    // 輸出: [hello, 123]

三、類型擦除:T 到底去哪了?

Java 的泛型是編譯期語法糖,在編譯過程中,T 會被替換成其限定類型(上限)。如果沒有顯式指定,則默認是 Object。看下面的例子

public class Box<T> {T value;void set(T value) { this.value = value; }T get() { return value; }
}

編譯后實際變成了:

public class Box {Object value;void set(Object value) { this.value = value; }Object get() { return value; }
}

這就意味著泛型信息在運行時根本就不存在,這就是類型擦除


四、類型擦除帶來的限制與問題

1. 泛型不能用于基本類型

Box<int> box; 

因為泛型最終會被擦除為 Object,而基本類型不能直接賦值給 Object,需要裝箱(autoboxing)。

2. 泛型不能創建數組

T[] arr = new T[10]; // 編譯錯誤

擦除后不知道 T 是什么類型,無法分配合適的數組類型。

3. 泛型類無法通過 instanceof 判斷類型參數

if (box instanceof Box<String>) {} // 編譯錯誤

因為泛型信息在運行期被擦除了,JVM 無法判斷類型。


五、橋方法:擦除下的多態陷阱

當子類重寫帶泛型的方法時,由于擦除后簽名可能不同(子類重寫父類方法后一般要求參數類型和數量不變,因為底層要生成一個方法簽名,這部分內容涉及到多態,動態鏈接的知識),為了保證運行時的多態性,編譯器會自動生成橋方法。例如下面這段代碼

class Parent<T> {T get() { return null; }
}class Child extends Parent<String> {@OverrideString get() { return "hello"; }
}

在實際編譯后為

class Child extends Parent {// 橋方法Object get() {return get(); // 調用下面的真實方法}// 實際的 get 方法String get() {return "hello";}
}

橋方法保證了子類方法可以在擦除后繼續覆蓋父類的方法,維護多態特性。


六、反射獲取泛型信息

雖然泛型信息在運行時被擦除,但某些泛型信息仍保留在 class 文件的元數據中,可以通過反射讀取。這部分簡單介紹一下,如下代碼

class GenericHolder<T> {}class StringHolder extends GenericHolder<String> {}public static void main(String[] args) {Type superClass = StringHolder.class.getGenericSuperclass();System.out.println(superClass);
}

總結

Java泛型通過類型擦除機制在編譯時期提供類型安全,但運行時類型信息會被擦除,因此在反射、數組等場景時需要格外注意

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908704.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908704.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908704.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Boot 從Socket 到Netty網絡編程(上):SOCKET 基本開發(BIO)與改進(NIO)

前言 無論是軟件還是硬件的本質都是要解決IO問題&#xff08;輸入、輸出&#xff09;&#xff0c;再說回網絡編程本質上都是基于TCP/UP的開發&#xff0c;socket是在此基礎上做的擴展與封裝&#xff0c;而Netty又是對socket做的封裝。本文旨在通過相關案例對socket進行探討。 一…

【大模型LLM學習】function call/agent學習記錄

【大模型LLM學習】function call/agent學習記錄 0 前言1 langchain實現function call2 調用本地模型3 微調本地模型3.1 few-shot調用Claude生成Q-A對3.2 tools格式3.3 agent微調格式3.4 swift微調 p.s. 0 前言 記錄一下使用langchain做簡單的function call/agent(或者說意圖識別…

【碎碎念】寶可夢 Mesh GO : 基于MESH網絡的口袋妖怪 寶可夢GO游戲自組網系統

目錄 游戲說明《寶可夢 Mesh GO》 —— 局域寶可夢探索Pokmon GO 類游戲核心理念應用場景Mesh 特性 寶可夢玩法融合設計游戲構想要素1. 地圖探索&#xff08;基于物理空間 廣播范圍&#xff09;2. 野生寶可夢生成與廣播3. 對戰系統4. 道具與通信5. 延伸玩法 安全性設計 技術選…

Puppeteer測試框架 - Node.js

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】

compose 組件 ---無ui組件

在 Jetpack Compose 中&#xff0c;確實存在不直接參與 UI 渲染的組件&#xff0c;它們主要用于邏輯處理、狀態管理或副作用控制。這些組件雖然沒有視覺界面&#xff0c;但在架構中扮演重要角色。以下是常見的非 UI 組件及其用途&#xff1a; 1. 無 UI 的 Compose 組件分類 (…

圖像超分辨率

圖像超分辨率 用AI當“像素偵探”&#xff0c;從模糊中重建合理高清細節&#xff0c;讓看不見的細節“無中生有”。 舉個生活例子 假設你有一張模糊的老照片&#xff0c;通過超分辨率技術&#xff0c;它能變成清晰的高清照片&#xff1a; 低分辨率圖像超分辨率結果 傳統放…

多線程語音識別工具

軟件介紹 本文介紹一款支持大廠接口的語音轉文字工具&#xff0c;具備免配置、免費使用的特點。 軟件特性 該工具是一款完全免費的桌面端應用程序&#xff0c;部署于開源社區平臺&#xff0c;其核心優勢在于整合了多家技術供應商的接口資源。 操作方式 用戶只需將音頻…

金融預測模型開發:數據預處理、機器學習預測與交易策略優化

金融預測模型開發:數據預處理、機器學習預測與交易策略優化 概述 本文將詳細介紹一個完整的金融預測模型開發流程,包含數據預處理、機器學習預測和交易策略優化三個核心模塊。我們使用Python實現一個端到端的解決方案,適用于股票價格預測和量化交易策略開發。 # 導入必要…

triton學習筆記7: GEMM相關

這是之前的學習筆記 triton puzzles part1triton puzzles part2triton puzzles part3triton tutorials part1triton tutorials: part2triton tutorails: part3 這是triton tutorials里最后一篇關于GEMM的系列了 GEMM的知識可以參考這篇&#xff0c;寫的非常詳細具體https://…

食養有方:進行性核上性麻痹患者的健康飲食指南

進行性核上性麻痹是一種罕見的神經系統變性疾病&#xff0c;患者常出現吞咽困難、肢體運動障礙等癥狀&#xff0c;合理的飲食安排不僅能保證營養供給&#xff0c;還能緩解不適&#xff0c;提高生活質量。以下是適合這類患者的健康飲食建議。 ?患者飲食應遵循 “均衡、細軟、易…

使用ORM Bee (ormbee) ,如何利用SQLAlchemy的模型生成數據庫表.

使用ORM Bee (ormbee) &#xff0c;如何利用SQLAlchemy的模型生成數據庫表. 將原來SQLAlchemy的模型&#xff0c;修改依賴為&#xff1a; from bee.helper import SQLAlchemy 然后就可以開始生成了。很簡單&#xff0c;主要是兩個接口。 db.create_all(True) #創建所有模型的表…

C# 使用正則表達式

C# 使用正則表達式 /// <summary> /// 測試正則表達式 /// </summary> private static void test022() {//檢查是否匹配&#xff1a;Regex.IsMatch(currencyValue, pattern); 或 new Regex(...).IsMatch(currencyValue)string pattern "\d{3,}";bool b…

LLMs之RLVR:《Absolute Zero: Reinforced Self-play Reasoning with Zero Data》翻譯與解讀

LLMs之RLVR&#xff1a;《Absolute Zero: Reinforced Self-play Reasoning with Zero Data》翻譯與解讀 導讀&#xff1a;Absolute Zero范式通過讓模型在沒有外部數據的情況下&#xff0c;自主提出和解決任務&#xff0c;實現了推理能力的顯著提升。Absolute Zero Reasoner (AZ…

信息最大化(Information Maximization)

信息最大化在目標域無標簽的域自適應任務中&#xff0c;它迫使模型在沒有真實標簽的情況下&#xff0c;對未標記數據產生高置信度且類別均衡的預測。此外&#xff0c;這些預測也可以作為偽標簽用于自訓練。 例如&#xff0c;在目標域沒有標簽時&#xff0c;信息最大化損失可以…

AUTOSAR實戰教程--標準協議棧實現DoIP轉DoCAN的方法

目錄 軟件架構 關鍵知識點 第一:PDUR的緩存作用 第二:CANTP的組包拆包功能 第三:流控幀的意義 配置過程 步驟0:ECUC模塊中PDU創建 步驟1:SoAD模塊維持不變 步驟2:DoIP模塊為Gateway功能添加Connection ?步驟3:DoIP模塊為Gateway新增LA/TA/SA ?步驟4:PDUR模…

設備驅動與文件系統:05 文件使用磁盤的實現

從文件使用磁盤的實現邏輯分享 我們現在講第30講&#xff0c;內容是文件使用磁盤的具體實現&#xff0c;也就是相關代碼是如何編寫的。上一節我們探討了如何從字符流位置算出盤塊號&#xff0c;這是文件操作磁盤的核心。而這節課&#xff0c;我們將深入研究實現這一核心功能的…

【PCIe總線】-- inbound、outbound配置

PCI、PCIe相關知識整理匯總 【PCIe總線】 -- PCI、PCIe相關實現 由之前的PCIe基礎知識可知&#xff0c;pcie的組成有&#xff1a;RC&#xff08;根節點&#xff09;、siwtch&#xff08;pcie橋&#xff09;、EP&#xff08;設備&#xff09;。 RC和EP&#xff0c;以及EP和EP能…

20250607在榮品的PRO-RK3566開發板的Android13系統下實現長按開機之后出現插入適配器不會自動啟動的問題的解決

20250607在榮品的PRO-RK3566開發板的Android13系統下實現長按開機之后出現插入適配器不會自動啟動的問題的解決 2025/6/7 17:20 緣起&#xff1a; 1、根據RK809的DATASHEET&#xff0c;短按開機【100ms/500ms】/長按關機&#xff0c;長按關機。6s/8s/10s 我在網上找到的DATASHE…

AIGC 基礎篇 Python基礎 02

1.bool類型 書接上回&#xff0c;我們上次最后講了三大數據類型&#xff0c;除了這三個之外&#xff0c;Python也有bool類型&#xff0c;也就是True和False。 a 2 print(a1) print(a2) 像這里&#xff0c;輸出的內容第一個是False&#xff0c;因為a的值為2&#xff0c;而第…

華為大規模——重塑生產力

華為大模型通過以下幾個方面重塑生產力&#xff1a; 提供強大算力支持 華為致力于構建領先的昇騰人工智能算力平臺&#xff0c;推出高性能昇騰AI集群&#xff0c;支持月級長期穩定訓練&#xff0c;可靠性業界領先。同時打造開放的昇騰計算平臺&#xff0c;兼容主流算子、框…