pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

Java中 ? extends T 和 ? super

本文主要介紹了Java中?extendsT和?superT的理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

? 通配符類型

  • <? extends T> 表示類型的上界,表示參數化類型的可能是T 或是 T的子類;
  • <? super T> 表示類型下界(Java Core中叫超類型限定),表示參數化類型是此類型的超類型(父類型),直至Object;

上界<? extends T>不能往里存,只能往外取

比如,我們現在定義:List<? extends T>首先你很容易誤解它為繼承于T的所有類的集合,你可能認為,你定義的這個List可以用來put任何T的子類,那么我們看下面的代碼:

import java.util.LinkedList;
import java.util.List;

public class test {
? ? public static void main(String[] args) {
? ? ? ? List<? extends Father> list = new LinkedList<>();
? ? ? ? list.add(new Son());
? ? }
}
class Human{
}
class Father extends Human{
}
class Son extends Father{
}
class LeiFeng extends Father {
}

list.add(new Son());這行會報錯:The method put(Son) is undefined for the type List<capture#1-of ? extends Father>

List<? extends Father> 表示 “具有任何從Son繼承類型的列表”,編譯器無法確定List所持有的類型,所以無法安全的向其中添加對象。可以添加null,因為null 可以表示任何類型。所以List 的add 方法不能添加任何有意義的元素,但是可以接受現有的子類型List 賦值。

你也許試圖這樣做:

List<? extends Father> list = new LinkedList<Son>();
list.add(new Son());

即使你指明了為Son類型,也不能用add方法添加一個Son對象。

list中為什么不能加入Father類和Father類的子類呢,我們來分析下。

List<? extends Father>表示上限是Father,下面這樣的賦值都是合法的

   List<? extends Father> list1 = new ArrayList<Father>();
   List<? extends Father> list2 = new ArrayList<Son>();
   List<? extends Father> list3 = new ArrayList<LeiFeng>();

如果List<? extends Father>支持add方法的話:

  • list1可以add Father和所有Father的子類;
  • list2可以add Son和所有Son的子類;
  • list3可以add LeiFeng和所有LeiFeng的子類。

下面代碼是編譯不通過的:

list1.add(new Father());//error
list1.add(new Son());//error

原因是編譯器只知道容器內是Father或者它的派生類,但具體是什么類型不知道。可能是Father?可能是Son?也可能是LeiFeng,XiaoMing?編譯器在看到后面用Father賦值以后,集合里并沒有限定參數類型是“Father“。而是標上一個占位符:CAP#1,來表示捕獲一個Father或Father的子類,具體是什么類不知道,代號CAP#1。然后無論是想往里插入Son或者LeiFeng或者Father編譯器都不知道能不能和這個CAP#1匹配,所以就都不允許。

所以通配符<?>和類型參數的區別就在于,對編譯器來說所有的T都代表同一種類型。比如下面這個泛型方法里,三個T都指代同一個類型,要么都是String,要么都是Integer。

public <T> List<T> fill(T... t);

但通配符<?>沒有這種約束,List<?>單純的就表示:集合里放了一個東西,是什么我不知道。

所以這里的錯誤就在這里,List<? extends Father>里什么都放不進去。

List<? extends Father> list不能進行add,但是,這種形式還是很有用的,雖然不能使用add方法,但是可以在初始化的時候一個Season指定不同的類型。比如:

List<? extends Father> list1 = getFatherList();//getFatherList方法會返回一個Father的子類的list

另外,由于我們已經保證了List中保存的是Father類或者他的某一個子類,所以,可以用get方法直接獲得值:

List<? extends Father> list1 = new ArrayList<>();
Father father = list1.get(0);//讀取出來的東西只能存放在Father或它的基類里。
Object object = list1.get(0);//讀取出來的東西只能存放在Father或它的基類里。
Human human = list1.get(0);//讀取出來的東西只能存放在Father或它的基類里。
Son son = (Son)list1.get(0);

下界<? super T>不影響往里存,但往外取只能放在Object對象里

下界用super進行聲明,表示參數化的類型可能是所指定的類型,或者是此類型的父類型,直至Object。

//super只能添加Father和Father的子類,不能添加Father的父類,讀取出來的東西只能存放在Object類里
List<? super Father> list = new ArrayList<>();
list.add(new Father());
list.add(new Human());//compile error 
list.add(new Son());
Father person1 = list.get(0);//compile error 
Son son = list.get(0);//compile error 
Object object1 = list.get(0);

因為下界規定了元素的最小粒度的下限,實際上是放松了容器元素的類型控制。既然元素是Father的基類,那往里存粒度比Father小的都可以。出于對類型安全的考慮,我們可以加入Father對象或者其任何子類(如Son)對象,但由于編譯器并不知道List的內容究竟是Father的哪個超類,因此不允許加入特定的任何超類(如Human)。而當我們讀取的時候,編譯器在不知道是什么類型的情況下只能返回Object對象,因為Object是任何Java類的最終祖先類。但這樣的話,元素的類型信息就全部丟失了。

PECS原則

最后看一下什么是PECS(Producer Extends Consumer Super)原則,已經很好理解了:

  • 頻繁往外讀取內容的,適合用上界Extends。
  • 經常往里插入的,適合用下界Super。

總結

  • extends 可用于返回類型限定,不能用于參數類型限定(換句話說:? extends xxx 只能用于方法返回類型限定,jdk能夠確定此類的最小繼承邊界為xxx,只要是這個類的父類都能接收,但是傳入參數無法確定具體類型,只能接受null的傳入)。
  • super 可用于參數類型限定,不能用于返回類型限定(換句話說:? supper xxx 只能用于方法傳參,因為jdk能夠確定傳入為xxx的子類,返回只能用Object類接收)。
  • ? 既不能用于方法參數傳入,也不能用于方法返回。

帶有super超類型限定的通配符可以向泛型對象中寫入,帶有extends子類型限定的通配符可以向泛型對象讀取。

到此這篇關于Java中 ? extends T 和 ? super T的理解的文章就介紹到這了,更多相關Java中 ? extends T 和 ? super T內容請搜索html5模板網以前的文章希望大家以后多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

主站蜘蛛池模板: 深圳天际源广告-形象堆头,企业文化墙,喷绘,门头招牌设计制作专家 | 钢衬四氟管道_钢衬四氟直管_聚四氟乙烯衬里管件_聚四氟乙烯衬里管道-沧州汇霖管道科技有限公司 | 谷歌关键词优化-外贸网站优化-Google SEO小语种推广-思亿欧外贸快车 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 艾默生变频器,艾默生ct,变频器,ct驱动器,广州艾默生变频器,供水专用变频器,风机变频器,电梯变频器,艾默生变频器代理-广州市盟雄贸易有限公司官方网站-艾默生变频器应用解决方案服务商 | 聚合氯化铝厂家-聚合氯化铝铁价格-河南洁康环保科技 | 铜镍-康铜-锰铜-电阻合金-NC003 - 杭州兴宇合金有限公司 | 沙盘模型公司_沙盘模型制作公司_建筑模型公司_工业机械模型制作厂家 | 华夏医界网_民营医疗产业信息平台_民营医院营销管理培训 | 五轴加工中心_数控加工中心_铝型材加工中心-罗威斯 | LED投光灯-工矿灯-led路灯头-工业灯具 - 山东普瑞斯照明科技有限公司 | 智能型高压核相仪-自动开口闪点测试仪-QJ41A电雷管测试仪|上海妙定 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 西安微信朋友圈广告投放_微信朋友圈推广_西安度娘网络科技有限公司 | 石膏基自流平砂浆厂家-高强石膏基保温隔声自流平-轻质抹灰石膏粉砂浆批发-永康市汇利建设有限公司 | 专注提供国外机电设备及配件-工业控制领域一站式服务商-深圳市华联欧国际贸易有限公司 | 可程式恒温恒湿试验箱|恒温恒湿箱|恒温恒湿试验箱|恒温恒湿老化试验箱|高低温试验箱价格报价-广东德瑞检测设备有限公司 | 圆周直径尺-小孔内视镜-纤维研磨刷-东莞市高腾达精密工具 | 化工ERP软件_化工新材料ERP系统_化工新材料MES软件_MES系统-广东顺景软件科技有限公司 | 卫生纸复卷机|抽纸机|卫生纸加工设备|做卫生纸机器|小型卫生纸加工需要什么设备|卫生纸机器设备多少钱一台|许昌恒源纸品机械有限公司 | 电镀电源整流器_高频电解电源_单脉双脉冲电源 - 东阳市旭东电子科技 | 气动隔膜阀_气动隔膜阀厂家_卫生级隔膜阀价格_浙江浙控阀门有限公司 | 外贮压-柜式-悬挂式-七氟丙烷-灭火器-灭火系统-药剂-价格-厂家-IG541-混合气体-贮压-非贮压-超细干粉-自动-灭火装置-气体灭火设备-探火管灭火厂家-东莞汇建消防科技有限公司 | 水厂自动化|污水处理中控系统|水利信息化|智慧水务|智慧农业-山东德艾自动化科技有限公司 | 背压阀|减压器|不锈钢减压器|减压阀|卫生级背压阀|单向阀|背压阀厂家-上海沃原自控阀门有限公司 本安接线盒-本安电路用接线盒-本安分线盒-矿用电话接线盒-JHH生产厂家-宁波龙亿电子科技有限公司 | 青岛侦探_青岛侦探事务所_青岛劝退小三_青岛调查出轨取证公司_青岛婚外情取证-青岛探真调查事务所 | 炉门刀边腹板,焦化设备配件,焦化焦炉设备_沧州瑞创机械制造有限公司 | 恒温恒湿箱(药品/保健品/食品/半导体/细菌)-兰贝石(北京)科技有限公司 | 小程序开发公司-小程序制作-微信小程序开发-小程序定制-咏熠软件 | 细沙回收机-尾矿干排脱水筛设备-泥石分离机-建筑垃圾分拣机厂家-青州冠诚重工机械有限公司 | 悬浮拼装地板_篮球场木地板翻新_运动木地板价格-上海越禾运动地板厂家 | GAST/BRIWATEC/CINCINNATI/KARL-KLEIN/ZIEHL-ABEGG风机|亚喜科技 | 首页-浙江橙树网络技术有限公司| 长沙广告公司|长沙广告制作设计|长沙led灯箱招牌制作找望城湖南锦蓝广告装饰工程有限公司 | 体视显微镜_荧光生物显微镜_显微镜报价-微仪光电生命科学显微镜有限公司 | 气弹簧定制-气动杆-可控气弹簧-不锈钢阻尼器-工业气弹簧-可调节气弹簧厂家-常州巨腾气弹簧供应商 | 移动机器人产业联盟官网| 直流电能表-充电桩电能表-导轨式电能表-智能电能表-浙江科为电气有限公司 | 河北码上网络科技|邯郸小程序开发|邯郸微信开发|邯郸网站建设 | 分光色差仪,测色仪,反透射灯箱,爱色丽分光光度仪,美能达色差仪维修_苏州欣美和仪器有限公司 | 一体化净水器_一体化净水设备_一体化水处理设备-江苏旭浩鑫环保科技有限公司 |