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

Java泛型使用一些常見報錯總結(jié)

 更新時間:2026年01月14日 11:37:16   作者:xzkyd?outpaper  
泛型是Java中一種強(qiáng)大的特性,它允許我們編寫類型安全且可重用的代碼,這篇文章主要介紹了Java泛型使用一些常見報錯總結(jié)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、什么時候使用泛型會報錯?

報錯幾乎都發(fā)生在編譯時期,這正是泛型保護(hù)我們的地方。它們源于對泛型規(guī)則(特別是繼承規(guī)則)的誤解。

錯誤1:誤認(rèn)為泛型類型存在繼承關(guān)系(最常見?。?/h3>

核心規(guī)則( invariance - 不可變性):

Box<String> 和 Box<Object> 沒有任何繼承關(guān)系,即使 String 是 Object 的子類。

List<String> strList = new ArrayList<>();
List<Object> objList = strList; // 編譯錯誤! incompatible types(不兼容的類型)

為什么會報錯?

如果編譯器允許這樣做,就會破壞類型安全。因?yàn)?nbsp;objList 的類型是 List<Object>,意味著你可以向里面添加任何 Object 的子類,比如 Integer。

// 假設(shè)上面的代碼不報錯,會發(fā)生什么:
objList.add(new Integer(100)); // 這看起來是合法的,因?yàn)镮nteger是Object的子類
String firstElement = strList.get(0); // ?。?!運(yùn)行時錯誤:ClassCastException
// 你試圖從一個聲稱只裝String的列表里,取出一個Integer并當(dāng)成String

編譯器通過報錯阻止了這種可能引發(fā)運(yùn)行時災(zāi)難的代碼。這就是泛型提供的編譯期類型安全。

錯誤2:試圖創(chuàng)建泛型數(shù)組

T[] array = new T[10]; // 編譯錯誤! generic array creation(無法創(chuàng)建泛型數(shù)組)
List<String>[] listArray = new List<String>[10]; // 編譯錯誤!

為什么會報錯?

因?yàn)轭愋筒脸?。在運(yùn)行時,T 和 String 都被擦除了,變成了 Object。JVM 無法在創(chuàng)建數(shù)組時確認(rèn) array 和 listArray 的具體類型(數(shù)組需要知道其確切的組件類型以強(qiáng)制保證類型安全)。如果允許創(chuàng)建,可能會導(dǎo)致上述的類型安全問題。

繞過方法(但不安全):

你可以創(chuàng)建一個 Object[] 然后強(qiáng)制轉(zhuǎn)型,但這會收到編譯器警告,且需要自己保證類型安全。

List<String>[] listArray = (List<String>[]) new List<?>[10]; // 有警告,但不報錯

錯誤3:誤用通配符集合的寫入操作

List<? extends Number> numbers = new ArrayList<Integer>();
numbers.add(new Integer(100)); // 編譯錯誤!
numbers.add(new Float(3.14f)); // 編譯錯誤!
numbers.add(null); // 這是唯一可以的,因?yàn)閚ull沒有類型

為什么會報錯?

List<? extends Number> 的意思是“一個只讀的列表,其元素是某種未知的、繼承自 Number 的類型”。它可能是 ArrayList<Integer>,也可能是 ArrayList<Double>。編譯器無法確定到底是哪一種,所以為了絕對的類型安全,它禁止你加入任何元素(除了 null),因?yàn)槟憧赡軙?nbsp;Double 加到 ArrayList<Integer> 里。

錯誤4:誤用通配符集合的讀取操作

List<? super Integer> list = new ArrayList<Number>();
Integer num = list.get(0); // 編譯錯誤!
Number num2 = list.get(0); // 編譯錯誤!
Object obj = list.get(0); // 這是唯一可以的

為什么會報錯?

List<? super Integer> 的意思是“一個只寫的列表,其元素是某種未知的、Integer 的父類型”。你從里面取出的元素,編譯器只能確定它是 Integer 的某個父類,但無法確定具體是 Number 還是 Object。因此,為了保證安全,它只允許你賦值給最頂層的 Object 引用。

二、泛型“繼承”關(guān)系的正確認(rèn)知

如何理解這張圖:

  1. 不變性 (Invariance - 紅色部分):這是最根本的規(guī)則。List<String> 和 List<Object> 在類型系統(tǒng)上是完全不同的類型,沒有繼承關(guān)系。你不能將它們互相賦值。試圖這么做是絕大多數(shù)編譯錯誤的根源。

  2. 協(xié)變 (Covariance - 通過 ? extends 實(shí)現(xiàn),綠色部分):雖然 List<Integer> 不是 List<Number> 的子類,但你可以通過上界通配符 List<? extends Number> 來獲得一個“只讀”的、安全的“繼承”視圖。一個 ArrayList<Integer> 可以被當(dāng)作一個 List<? extends Number> 來使用。這模擬了協(xié)變(子類容器可以被視為父類容器)。

  3. 逆變 (Contravariance - 通過 ? super 實(shí)現(xiàn),綠色部分):同樣,你可以通過下界通配符 List<? super Integer> 來獲得一個“只寫”的、安全的“繼承”視圖。一個 ArrayList<Number> 甚至 ArrayList<Object> 都可以被當(dāng)作一個 List<? super Integer> 來使用。這模擬了逆變(父類容器可以被視為子類容器,但用途相反)。

記?。?/strong>

  • <T>: 用于當(dāng)你既需要“讀”也需要“寫”操作時。這是最常用、最直接的方式。

  • <? extends T>: 只讀。當(dāng)你只需要從集合中獲取元素時使用(Producer)。

  • <? super T>: 只寫。當(dāng)你只需要向集合中添加元素時使用(Consumer)。

三、常見問題總結(jié)

Q:“談?wù)凧ava泛型中使用不當(dāng)會導(dǎo)致的問題和泛型的繼承關(guān)系。”

A:

“使用泛型最容易出錯的地方是對泛型容器繼承關(guān)系的誤解。核心規(guī)則是泛型具有不變性Container<SubClass> 和 Container<SuperClass> 沒有繼承關(guān)系,即使 SubClass 繼承自 SuperClass。試圖將它們相互賦值是主要的編譯錯誤來源。

之所以這樣設(shè)計,是為了保證絕對的編譯期類型安全。如果允許這種賦值,就可以把 SuperClass 對象放入一個聲明為只裝 SubClass 的容器中,從而在后續(xù)讀取時引發(fā)運(yùn)行時 ClassCastException。

為了在需要時實(shí)現(xiàn)類似繼承的靈活性,Java引入了通配符:

  • <? extends T> 實(shí)現(xiàn)了協(xié)變,讓我們能安全地讀取元素,將容器視為元素的生產(chǎn)者。

  • <? super T> 實(shí)現(xiàn)了逆變,讓我們能安全地寫入元素,將容器視為元素的消費(fèi)者。

其他常見錯誤還包括試圖創(chuàng)建泛型數(shù)組或?qū)嵗愋蛥?shù),這些都源于泛型在運(yùn)行時類型信息被擦除的實(shí)現(xiàn)機(jī)制。

PECS(Producer-Extends, Consumer-Super) 原則是指導(dǎo)我們正確使用通配符、避免編譯錯誤的最佳實(shí)踐。理解了不變性是基礎(chǔ),協(xié)變和逆變是工具,就能絕大多數(shù)泛型相關(guān)的編譯錯誤。

到此這篇關(guān)于Java泛型使用一些常見報錯總結(jié)的文章就介紹到這了,更多相關(guān)Java泛型使用報錯內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

榕江县| 榆中县| 抚州市| 南陵县| 安平县| 滨州市| 韩城市| 大宁县| 西乌珠穆沁旗| 佳木斯市| 东莞市| 太原市| 东丽区| 江孜县| 旬邑县| 民乐县| 银川市| 榆中县| 临泉县| 武川县| 新巴尔虎左旗| 万年县| 体育| 阿坝县| 乃东县| 锡林浩特市| 中卫市| 晋江市| 崇文区| 简阳市| 大田县| 嘉黎县| 阿克| 正宁县| 林西县| 晋宁县| 惠东县| 泽州县| 融水| 阜南县| 虹口区|