Java泛型初學(xué)者之上、下界通配符的深入理解
泛型的由來(lái)
為什么需要泛型
Java的數(shù)據(jù)類(lèi)型一般都是在定義時(shí)就需要確定,這種強(qiáng)制的好處就是類(lèi)型安全,不會(huì)出現(xiàn)像弄一個(gè)ClassCastException的數(shù)據(jù)給jvm,數(shù)據(jù)安全那么執(zhí)行的class就會(huì)很穩(wěn)定。但是假如說(shuō)我不知道這個(gè)參數(shù)要傳什么類(lèi)型的,因?yàn)楣拘枨笤谧?,如果?xiě)死的那就只能便以此需求就改一次,很麻煩。sun公司也注意到這個(gè)問(wèn)題,這樣會(huì)讓代碼的靈活性降低,他們就研究出了泛型。
泛型初識(shí)
什么是泛型,可以字面理解就是一個(gè)泛泛的類(lèi)型,他是不確定的,在Java代碼編譯的時(shí)候用泛型是不會(huì)出錯(cuò)的,而在運(yùn)行期時(shí)就會(huì)報(bào)錯(cuò),說(shuō)你這種第一是不合理的。這是為什么呢。因?yàn)闉榱颂岣哽`活性,就在編譯時(shí)期將條件放寬,但是泛型一定要在運(yùn)行的時(shí)候告訴jvm你給我的數(shù)據(jù)到底是什么類(lèi)型的,否則jvm會(huì)是懵逼的。所以泛型的好處就是將類(lèi)型的靈活性提高,也只是在Java語(yǔ)法的基礎(chǔ)上提高,不過(guò)泛型還是比較實(shí)用的。
何時(shí)使用泛型
泛型的應(yīng)用場(chǎng)景就是應(yīng)用在模型(可以理解為存儲(chǔ)數(shù)據(jù)的盒子),我為了這個(gè)盒子適用更多的地方我就用將需要存入的數(shù)據(jù)用一個(gè)泛型表示,當(dāng)然可以傳入多值。如果是相同類(lèi)型的對(duì)象就用一個(gè)泛型的數(shù)組比較好,學(xué)過(guò)集合的小伙伴應(yīng)該都知道,沒(méi)學(xué)過(guò)的那你應(yīng)該補(bǔ)補(bǔ)課了。
泛型的語(yǔ)法
public class A<T extends B>{ T t; }
泛型的缺點(diǎn)或者為什么需要上、下邊界
泛型的雖然強(qiáng)大,但是世界上任何東西東部是完美的。它也有缺陷。比如說(shuō)我有一個(gè)盒子我想裝蘋(píng)果,但是我還可能想裝香蕉那怎么辦。那還不好說(shuō),在給一個(gè)參數(shù)不就行了,那十個(gè)呢,二十個(gè)呢。em....的確是。如果說(shuō)我們想裝的東西都屬于一個(gè)類(lèi)并且只要是這個(gè)類(lèi)的子類(lèi)就可以裝。這個(gè)想法sun為我們想好了。那就是用上邊界通配符。語(yǔ)法是 T是泛型,M是T的父類(lèi)。我們就定義一個(gè)水果類(lèi)(Fruit),盛裝就容器就是盤(pán)子(Dish),現(xiàn)在我們就可以裝任何水果了,不錯(cuò)吧!
上邊界Java代碼
public class Dish<T extends Fruit>{ private T fruitChild; public Dish(T fruitChild){ this.fruitChild = fruitChild; } public T getFruitChild(){ return fruitChild; } public void setFruitChild(T f){ this.fruitChild = f; } public static void main(String[] args){ Dish dish = new Dish<apple>(); Apple apple = new apple(); //apple must be Fruit child; dish.setFruitChild(apple); system.out.printf(dish.getFruitChild); } }
下邊界Java代碼
public class Dish<T super Apple>{ private T appleFather; public Dish(T appleFather){ this.appleFather = appleFather; } public T getAppleFather(){ return appleFather; } public void setAppleFather(T f){ this.appleFather = f; } public static void main(String[] args){ Dish dish = new Dish<Fruit>(); Fruit fruit = new Fruit(); //fruit must be apple son; dish.setAppleFather(fruit); system.out.printf(dish.getAppleFather); } }
什么是上邊界通配符
當(dāng)泛型T給定形如 的A類(lèi)型到A類(lèi)型任何子類(lèi)的限制域,可以匹配任何在此限制域中的類(lèi)型,此種表示叫上邊界通配符。
上邊界通配符理解
什么是下邊界通配符
當(dāng)泛型T給定形如 的A類(lèi)型到A類(lèi)型任何父類(lèi)的限制域,可以匹配任何在此限制域中的類(lèi)型,此種表示叫下邊界通配符。
下邊界通配符理解#
上下邊界通配符的缺點(diǎn)
上界<? extends T>不能往里存,只能往外取。
解釋
因?yàn)榫幾g器只知道傳入的是T的子類(lèi),但具體是哪一個(gè)編譯器不知道,他只標(biāo)注了一個(gè)占位符,當(dāng)?傳過(guò)來(lái)時(shí),他不知道這能不能和占位符匹配,所以set不了。
下界<? super T>不影響往里存,但往外取只能放在Object對(duì)象里。
解釋
因?yàn)橄逻吔缫呀?jīng)限制了?的粒度,他只可能是T本身或者是T的父類(lèi)。我們想想,我想要一個(gè)T,你卻返回給我一個(gè)比T小的Object,這樣我們就因?yàn)榫葥p失而拿不到想要的數(shù)據(jù)了。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
關(guān)于SpringBoot+Mybatis報(bào)MapperScan.factoryBean()問(wèn)題
解決SpringBoot+Mybatis中的MapperScan.factoryBean()問(wèn)題,讓你的項(xiàng)目運(yùn)行更順暢!本指南將帶你一步步解決這個(gè)問(wèn)題,讓你的開(kāi)發(fā)過(guò)程更加高效,不要錯(cuò)過(guò)這個(gè)實(shí)用指南,快來(lái)一探究竟吧!2024-02-02MyBatis中動(dòng)態(tài)SQL語(yǔ)句@Provider的用法
本文主要介紹了MyBatis中動(dòng)態(tài)SQL語(yǔ)句@Provider的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06javabean servlet jsp實(shí)現(xiàn)分頁(yè)功能代碼解析
這篇文章主要為大家詳細(xì)解析了javabean servlet jsp實(shí)現(xiàn)分頁(yè)功能代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Java替換中使用正則表達(dá)式實(shí)現(xiàn)中間模糊匹配的方法
今天小編就為大家分享一篇Java替換中使用正則表達(dá)式實(shí)現(xiàn)中間模糊匹配的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07因Spring AOP導(dǎo)致@Autowired依賴(lài)注入失敗的解決方法
這篇文章主要給大家介紹了因Spring AOP導(dǎo)致@Autowired依賴(lài)注入失敗的解決方法,文中通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-07-07Java多線(xiàn)程并發(fā)之線(xiàn)程池任務(wù)請(qǐng)求攔截測(cè)試實(shí)例
這篇文章主要介紹了Java多線(xiàn)程并發(fā)之線(xiàn)程池任務(wù)請(qǐng)求攔截測(cè)試實(shí)例,隊(duì)列中永遠(yuǎn)沒(méi)有線(xiàn)程被加入,即使線(xiàn)程池已滿(mǎn),也不會(huì)導(dǎo)致被加入排隊(duì)隊(duì)列,實(shí)現(xiàn)了只有線(xiàn)程池存在空閑線(xiàn)程的時(shí)候才會(huì)接受新任務(wù)的需求,需要的朋友可以參考下2023-12-12Java數(shù)據(jù)導(dǎo)出功能之導(dǎo)出Excel文件實(shí)例
這篇文章主要介紹了Java數(shù)據(jù)導(dǎo)出功能之導(dǎo)出Excel文件實(shí)例,本文給出了jar包的下載地址,并給出了導(dǎo)出Excel文件代碼實(shí)例,需要的朋友可以參考下2015-06-06Spring-AOP 靜態(tài)正則表達(dá)式方法如何匹配切面
這篇文章主要介紹了Spring-AOP 靜態(tài)正則表達(dá)式方法如何匹配切面的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java使用Sharding-JDBC分庫(kù)分表進(jìn)行操作
Sharding-JDBC 是無(wú)侵入式的 MySQL 分庫(kù)分表操作工具,本文主要介紹了Java使用Sharding-JDBC分庫(kù)分表進(jìn)行操作,感興趣的可以了解一下2021-08-08