日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 泛型中? super T和? extends T的区别

發布時間:2025/3/21 java 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 泛型中? super T和? extends T的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接? ? ? ? ??李璟(jlee381344197@gmail.com)

經常發現有List<? super T>、Set<? extends T>的聲明,是什么意思呢?<? super T>表示包括T在內的任何T的父類,<? extends T>表示包括T在內的任何T的子類,下面我們詳細分析一下兩種通配符具體的區別。

?

extends

List<? extends Number> foo3的通配符聲明,意味著以下的賦值是合法的:

01// Number "extends" Number (in this context)
02?
03List<??extends?Number> foo3 =?new?ArrayList<??extends?Number>();
04?
05// Integer extends Number
06?
07List<??extends?Number> foo3 =?new?ArrayList<??extends?Integer>();
08?
09// Double extends Number
10?
11List<??extends?Number> foo3 =?new?ArrayList<??extends?Double>();
  • 讀取操作通過以上給定的賦值語句,你一定能從foo3列表中讀取到的元素的類型是什么呢?你可以讀取到Number,因為以上的列表要么包含Number元素,要么包含Number的類元素。

    你不能保證讀取到Integer,因為foo3可能指向的是List<Double>。

    你不能保證讀取到Double,因為foo3可能指向的是List<Integer>。

  • 寫入操作過以上給定的賦值語句,你能把一個什么類型的元素合法地插入到foo3中呢?

    你不能插入一個Integer元素,因為foo3可能指向List<Double>。

    你不能插入一個Double元素,因為foo3可能指向List<Integer>。

    你不能插入一個Number元素,因為foo3可能指向List<Integer>。

    你不能往List<? extends T>中插入任何類型的對象,因為你不能保證列表實際指向的類型是什么,你并不能保證列表中實際存儲什么類型的對象。唯一可以保證的是,你可以從中讀取到T或者T的子類。

  • super

    現在考慮一下List<? super T>。

    List<? super Integer> foo3的通配符聲明,意味著以下賦值是合法的:

    01// Integer is a "superclass" of Integer (in this context)
    02?
    03List<??super?Integer> foo3 =?new?ArrayList<Integer>();
    04?
    05// Number is a superclass of Integer
    06?
    07List<??super?Integer> foo3 =?new?ArrayList<Number>();
    08?
    09// Object is a superclass of Integer
    10?
    11List<??super?Integer> foo3 =?new?ArrayList<Object>();
  • 讀取操作通過以上給定的賦值語句,你一定能從foo3列表中讀取到的元素的類型是什么呢?你不能保證讀取到Integer,因為foo3可能指向List<Number>或者List<Object>。

    你不能保證讀取到Number,因為foo3可能指向List<Object>。

    唯一可以保證的是,你可以讀取到Object或者Object子類的對象(你并不知道具體的子類是什么)。

  • 寫入操作通過以上給定的賦值語句,你能把一個什么類型的元素合法地插入到foo3中呢?你可以插入Integer對象,因為上述聲明的列表都支持Integer。

    你可以插入Integer的子類的對象,因為Integer的子類同時也是Integer,原因同上。

    你不能插入Double對象,因為foo3可能指向ArrayList<Integer>。

    你不能插入Number對象,因為foo3可能指向ArrayList<Integer>。

    你不能插入Object對象,因為foo3可能指向ArrayList<Integer>。

  • PECS

    請記住PECS原則:生產者(Producer)使用extends,消費者(Consumer)使用super。

    • 生產者使用extends

    如果你需要一個列表提供T類型的元素(即你想從列表中讀取T類型的元素),你需要把這個列表聲明成<? extends T>,比如List<? extends Integer>,因此你不能往該列表中添加任何元素。

    • 消費者使用super

    如果需要一個列表使用T類型的元素(即你想把T類型的元素加入到列表中),你需要把這個列表聲明成<? super T>,比如List<? super Integer>,因此你不能保證從中讀取到的元素的類型。

    • 即是生產者,也是消費者

    如果一個列表即要生產,又要消費,你不能使用泛型通配符聲明列表,比如List<Integer>。

    例子

    請參考java.util.Collections里的copy方法(JDK1.7):

    ?

    我們可以從Java開發團隊的代碼中獲得到一些啟發,copy方法中使用到了PECS原則,實現了對參數的保護。

    ?

    原創文章,轉載請注明:?轉載自并發編程網 – ifeve.com本文鏈接地址:?泛型中? super T和? extends T的區別

    總結

    以上是生活随笔為你收集整理的Java 泛型中? super T和? extends T的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。