Java泛型通配符詳解:搞懂?/extends/super用法,避開集合操作踩坑點

上次跟你們聊了泛型的基礎用法,今天接著往下說 —— 泛型里還有個挺重要的概念叫 “通配符”,就是那個問號 “?”,很多人第一次見都懵:這玩意兒跟普通泛型有啥區別?為啥有時候非得用它不可?小索奇當初也卡這兒好久,后來拿實際例子一琢磨,才徹底明白它的用處。

先給你出個題:假如你寫了個方法,要打印所有 List 集合里的元素,不管這個 List 裝的是 String、Integer 還是別的類型,該咋寫?

你可能會想,直接用 List不就行了?比如這樣:

public static void printList(List list) {

for (T item : list) {

System.out.println(item);

}

}

這么寫沒問題,但還有個更簡潔的方式 —— 用通配符 “?”:

public static void printList (List<?> list) {

for (Object item : list) {

System.out.println (item);

}

}

看出區別沒?用通配符的話,不用定義泛型參數,代碼更短。而且這兩種寫法效果一樣,不管你傳 List還是 List,都能正常打印。那為啥要有兩種寫法呢?其實核心區別在于:如果方法里不需要用到泛型的具體類型,只用通配符就夠了;要是需要操作具體類型(比如給集合加元素),就得用

比如你想寫個方法,給 List 里加一個默認元素,這時候用通配符就不行了:

// 這段代碼會編譯報錯!

public static void addDefault (List<?> list) {

list.add ("默認值"); // 報錯:無法確定?的類型,不能加 String

}

這背后的原因是啥呢?因為通配符 “?” 代表 “未知類型”,編譯器不知道這個 List 到底裝的是啥,自然不敢讓你隨便加元素 —— 萬一人家是 List,你硬塞個 String 進去,不就亂套了?

但用就能搞定:

public static void addDefault(List list, T defaultValue) {

list.add(defaultValue);

}

調用的時候指定類型就行,比如給 List加默認值:

List strList = new ArrayList<>();

addDefault (strList, "默認值"); // 沒問題

是不是一下子就懂了?簡單說就是:通配符適合 “只讀” 場景(比如打印集合),泛型參數適合 “讀寫” 場景(比如給集合加元素)。

除了單純的 “?”,通配符還有兩種常用寫法:<? extends T > 和 <? super T>,這倆也特容易搞混,小索奇當初記了好幾天才分清。

先看 <? extends T>,它代表 “T 及其子類”。比如 <? extends Number>,就包括 Integer、Double、Long 這些 Number 的子類。這種寫法的特點是 “能讀不能寫”(跟普通?類似,但多了類型限制)。比如你寫個方法,求所有 Number 類型集合的總和:

public static double sum (List<? extends Number> list) {

double total = 0;

for (Number num : list) {

total += num.doubleValue ();

}

return total;

}

不管你傳 List還是 List,都能算總和,因為它們都是 Number 的子類。但還是不能往里面加元素,比如 list.add (10) 會報錯 —— 因為編譯器不知道具體是 Integer 還是 Double,怕加錯類型。

再看 <? super T>,它代表 “T 及其父類”。比如 <? super Integer>,就包括 Number、Object 這些 Integer 的父類。這種寫法的特點是 “能寫不能讀”(或者說讀出來是 Object 類型)。比如你想寫個方法,給 List 里加多個 Integer 元素:

public static void addIntegers (List<? super Integer> list) {

list.add (1);

list.add (2); // 沒問題,因為?至少是 Integer 類型

}

調用的時候,傳 List、List甚至 List都能行。但讀元素的時候,只能用 Object 接收:

for (Object obj : list) {

// 要想用 Integer,得手動強轉

Integer num = (Integer) obj;

}

小索奇之前做統計功能時,就用 <? super Integer> 存過數據 —— 既可以存到 Integer 列表,也能存到 Number 列表,靈活度特別高。

最后給你總結個小口訣,記起來更方便:“上界 extends 能讀不能寫,下界 super 能寫不能讀,通配符?只讀不寫,泛型讀寫都能搞”。

你們平時寫代碼時,有沒有用過通配符卻踩了坑的?比如想加元素加不進去,或者不知道該用 extends 還是 super?可以在評論區跟小索奇聊聊,咱們一起把泛型這點事兒徹底搞明白~

搜索即興小索奇,點擊關注,加入社區群聊,獲取更多好用工具和資源

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

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

相關文章

EXCEL開發之路(二)跨表交互模擬—仙盟創夢IDE

在車輛租賃行業&#xff0c;數據的高效管理與分析對于企業的運營決策、資源調配及客戶服務優化至關重要。自建 Excel 實現多表統計交互&#xff0c;如同為行業裝上了效能驅動引擎&#xff0c;助力企業在復雜多變的市場環境中穩健前行。一、精準資源管理&#xff0c;優化車輛調配…

醫療AI時代的生物醫學Go編程:高性能計算與精準醫療的案例分析(八)

5.4 性能測試與結果分析 為了評估GoEHRStream的性能,我們設計測試模擬真實的醫院數據流場景,并測量關鍵指標。 5.4.1 實驗環境 硬件: CPU: Intel Xeon E-2288G (8 cores, 16 threads) RAM: 32 GB DDR4 Storage: 512 GB NVMe SSD (用于GoEHRStream和BadgerDB) Network: 1 G…

開關電源設計“反饋回路”部分器件分析

目錄 主要分析問題如下&#xff1a; 一、問題1 二、問題二 分析電路如下&#xff1a; 主要分析問題如下&#xff1a; 1、分析TL431芯片1、2兩引腳間并聯電阻和電容&#xff08;RC電路&#xff09;的作用&#xff1f; 2、PC817A光耦輸入兩個引腳間并聯電阻的作用&#xff1f;…

AI 編程新玩法:用 yunqi-saas-kit 框架制作小游戲,看廣告變現輕松賺錢?

AI 編程新玩法&#xff1a;用 yunqi-saas-kit 框架制作小游戲&#xff0c;看廣告變現輕松賺錢 在數字經濟快速發展的當下&#xff0c;AI 技術正不斷滲透到各個領域&#xff0c;其中 **#AI 編程憑借高效、便捷的優勢&#xff0c;成為不少開發者和創業者的新選擇。尤其是在小游戲…

Kafka 架構原理

一個kafka集群中包含一個或多個Producer、一個或多個broker、一個或多個ConsumerGrop以及一個Zookeeper集群。kafka通過Zookeeper管理kafka集群配置、leader副本的選舉、生產者的負載均衡等。Producer使用push模式將消息發布到broker,Consumer使用pull模式從broker訂閱并消費消…

用 PyTorch 搭建 CNN 實現 MNIST 手寫數字識別

在圖像識別領域&#xff0c;卷積神經網絡&#xff08;CNN&#xff09; 憑借其對空間特征的高效提取能力&#xff0c;成為手寫數字識別、人臉識別等任務的首選模型。而 MNIST&#xff08;手寫數字數據集&#xff09;作為入門級數據集&#xff0c;幾乎是每個深度學習學習者的 “第…

CTFshow系列——命令執行web61-68

本篇文章介紹了不同了方法進行題目的解析以及原因講解。 文章目錄Web61嘗試了一下&#xff0c;被過濾的payload如下&#xff1a;所以&#xff0c;根據上述思路&#xff0c;這里嘗試過的payload為&#xff1a;Web62&#xff08;同Web61&#xff09;Web63&#xff08;同Web62&…

.Net程序員就業現狀以及學習路線圖(二)

一、.NET程序員就業現狀分析 1. 市場需求與崗位分布 2025年.NET開發崗位全國招聘職位約1676個&#xff0c;占全國技術崗位的0.009%&#xff0c;主要集中在一線城市如深圳、上海等地。就業單位類型分布為&#xff1a;軟件公司占43.3%&#xff0c;研發機構占33.1%&#xff0c;物聯…

MTK Linux DRM分析(二十二)- MTK mtk_drm_crtc.c(Part1)

一、代碼分析 mtk_drm_crtc.c以mtk_crtc_comp_is_busy函數為界限進行拆分分析 static const struct drm_crtc_funcs mtk_crtc_funcs = {.set_config = drm_atomic_helper_set_config,.page_flip = drm_atomic_helper_page_flip,.destroy = mtk_drm_crtc_destroy,.reset = mtk…

stm32f103c8t6 led閃燈實驗

目錄 閃燈原理 2種接線方式控制閃燈 使用推挽接法 使用開漏接法 看原理圖 寫代碼 閃燈原理 LED燈有個2-10mA的電流就可以點亮 3.3/5100.006A6mA 2種接線方式控制閃燈 使用推挽接法 當設置推挽模式時&#xff0c;CPU控制寄存器寫0&#xff0c;IO引腳輸出低電壓&#xff0…

“我同意”按鈕別亂點——你的“職業EULA”漏洞掃描報告

尊敬的審核&#xff1a; 本人文章《“我同意”按鈕別亂點——你的“職業EULA”漏洞掃描報告》 1. 純屬技術交流&#xff0c;無任何違法內容 2. 所有法律引用均來自公開條文 3. 請依據《網絡安全法》第12條“不得無故刪除合法內容”處理 附&#xff1a;本文結構已通過區塊鏈存證…

Product Hunt 每日熱榜 | 2025-09-01

1. A01 標語&#xff1a;你個人的新聞助手 介紹&#xff1a;A01 是你的新聞助手&#xff0c;可以幫你關注你關心的任何話題。只需告訴它你想了解什么&#xff0c;它就能為你帶來最新的文章。 產品網站&#xff1a; 立即訪問 Product Hunt&#xff1a; View on Product Hunt…

【OpenFeign】基礎使用

【OpenFeign】基礎使用1. Feign介紹1.1 使用示例1.2 Feign與RPC對比1.3 SpringCloud Alibaba快速整合OpenFeign1.3.1 詳細代碼1. Feign介紹 1.什么是 Feign Feign 是 Netflix 開發的一個 聲明式的 HTTP 客戶端&#xff0c;在 Spring Cloud 中被廣泛使用。它的目標是&#xff…

訪問相同的url,相同入參的請求,Apifox/Postman可以正常響應結果,而本地調用不行(或結果不同)

文章目錄問題概述Apifox查看實際請求總結問題概述 開發中有一個需求需要去別的系統中拿數據&#xff0c;配置好相關參數后發起請求時發現響應結果和在Apifox上不同&#xff0c;Apifox上正常顯示數據&#xff0c;而本地調用后返回數據不存在。 這就很奇怪了&#xff0c;想了很多…

數據結構(C語言篇):(七)雙向鏈表

目錄 前言 一、概念與結構 二、雙向鏈表的實現 2.1 頭文件的準備 2.2 函數的實現 2.2.1 LTPushBack( )函數&#xff08;尾插&#xff09; &#xff08;1&#xff09;LTBuyNode( ) &#xff08;2&#xff09;LTInit( ) &#xff08;3&#xff09;LTPrint( ) &#x…

從拿起簡歷(resume)重新找工作開始聊起

經濟蕭條或經濟衰退在經濟相關學術上似乎有著嚴格的定義&#xff0c;我不知道我們的經濟是否已經走向了衰退或者蕭條&#xff0c;但有一點那是肯定的&#xff0c;那就現在我們的經濟肯定是不景氣的。經濟不景氣會怎么樣&#xff1f;是的&#xff0c;會有很多人失業&#xff0c;…

OS+MySQL+(其他)八股小記

魯迅先生曾經說過&#xff0c;每天進步一點點&#xff0c;媽媽夸我小天才。 依舊今日八股&#xff0c;這是我在多個文檔整合一起的&#xff0c;可能格式有些問題&#xff0c;請諒解。 操作系統 1.進程和線程的區別&#xff1f; 進程是代碼在數據集合的一次執行活動&#xff0c;…

Transformer的并行計算與長序列處理瓶頸總結

&#x1f31f; 第0層&#xff1a;極簡版&#xff08;30秒理解&#xff09;一句話核心&#xff1a;Transformer像圓桌會議——所有人都能同時交流&#xff08;并行優勢&#xff09;&#xff0c;但人越多會議越混亂&#xff08;長序列瓶頸&#xff09;。核心問題 并行優勢&#x…

Vue 3 useId 完全指南:生成唯一標識符的最佳實踐

&#x1f4d6; 概述 useId() 是 Vue 3 中的一個組合式 API 函數&#xff0c;用于生成唯一的標識符。它確保在服務端渲染&#xff08;SSR&#xff09;和客戶端渲染之間生成一致的 ID&#xff0c;避免水合不匹配的問題。 &#x1f3af; 基本概念 什么是 useId&#xff1f; useId…

CGroup 資源控制組 + Docker 網絡模式

1 CGroup 資源控制組1.1 為什么需要 CGroup - 容器本質 宿主機上一組進程 - 若無資源邊界&#xff0c;一個暴走容器即可拖垮整機 - CGroup 提供**內核級硬限制**&#xff0c;比 ulimit、nice 更可靠1.2 核心概念 3 件套 | 概念 | 一句話解釋 | 查看方式 | | Hierarchy | 樹…