Java:泛型知識(shí)知多少
定義
可理解為 適配廣泛的類(lèi)型,即參數(shù)化類(lèi)型,可以把類(lèi)型像方法的參數(shù)那樣進(jìn)行傳遞。
// 以ArrayList為示例
// 泛型T可以是任意類(lèi)
public class ArrayList<T> {
private T[] array;
//...
}
// 通過(guò)泛型的使用,就可創(chuàng)建多種類(lèi)型的ArrayList
// 1. 可存儲(chǔ)String的ArrayList:
ArrayList<String> strList = new ArrayList<String>();
// 相當(dāng)于
public class ArrayList<String> {
private String[] array;
//...
}
// 2. 可存儲(chǔ)Float的ArrayList:
ArrayList<Float> floatList = new ArrayList<Float>();
// 相當(dāng)于
public class ArrayList<Float> {
private Float[] array;
//...
}
意義(即為什么要使用泛型)
通過(guò)定義一種模板方式結(jié)構(gòu),從而保證類(lèi)型安全 & 匹配。下面將用ArrayList為示例作為說(shuō)明。
1. 背景
ArrayList的本質(zhì):一個(gè)可變的Object類(lèi)型數(shù)組
public class ArrayList {
private Object[] array;
// ...
}
2. 問(wèn)題
在使用ArrayList存儲(chǔ)不同類(lèi)型時(shí),需要強(qiáng)轉(zhuǎn)類(lèi)型,不然容易出現(xiàn)ClassCastException異常。如存儲(chǔ)String類(lèi)型:
// 獲取到ArrayList里的Object類(lèi)型時(shí),必須強(qiáng)制轉(zhuǎn)型為String
// 不然容易出現(xiàn)ClassCastException異常
ArrayList list = new ArrayList();
list.add("carson ho");
String first = (String) list.get(0);
3. 解決方案
使用泛型將ArrayList變成一種模板:ArrayList,就可以創(chuàng)建任意類(lèi)型的ArrayList。即:
// 泛型T可以是任意類(lèi)
public class ArrayList<T> {
private T[] array;
//...
}
// 多種類(lèi)型
// 1. 可存儲(chǔ)String的ArrayList:
ArrayList<String> strList = new ArrayList<String>();
// 相當(dāng)于
public class ArrayList<String> {
private String[] array;
//...
}
// 2. 可存儲(chǔ)Float的ArrayList:
ArrayList<Float> floatList = new ArrayList<Float>();
// 相當(dāng)于
public class ArrayList<Float> {
private Float[] array;
//...
}
作用
1.使編譯器可在編譯期間對(duì)類(lèi)型進(jìn)行檢查以提高類(lèi)型安全,減少運(yùn)行時(shí)由于對(duì)象類(lèi)型不匹配引發(fā)的異常;
2.運(yùn)行時(shí)所有的轉(zhuǎn)換都是強(qiáng)制、隱式的,大大提高了代碼的重用率。如對(duì)集合類(lèi)取數(shù)據(jù)時(shí),不需 對(duì)存儲(chǔ)的數(shù)據(jù) 進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)2換。
原理
基于 類(lèi)型擦除。即即 使用泛型時(shí)加上的類(lèi)型參數(shù),會(huì)在編譯器在編譯時(shí)去掉所以,在生成的 Java 字節(jié)碼中,不包含泛型中的類(lèi)型信息。這里需要特別說(shuō)明的是:
- Java中的泛型是在編譯器層次實(shí)現(xiàn),編譯器在編譯時(shí)盡可能的發(fā)現(xiàn)可能出錯(cuò)的地方,但仍無(wú)法避免在運(yùn)行時(shí)刻出現(xiàn)類(lèi)型轉(zhuǎn)換異常的情況;
- 在代碼中定義的List 、List等類(lèi)型,在編譯后都會(huì)變成List
- JVM看到的只是List,而由泛型附加的類(lèi)型信息對(duì)JVM來(lái)說(shuō)是不可見(jiàn)的
同時(shí)需要特別注意的是:
- 在無(wú)泛型的情況下,通常是使用Object類(lèi)型來(lái)進(jìn)行多種類(lèi)型數(shù)據(jù)的操作,此時(shí)操作最多的是針對(duì)該Object進(jìn)行數(shù)據(jù)的強(qiáng)制轉(zhuǎn)換
- 而這種轉(zhuǎn)換是基于開(kāi)發(fā)者對(duì)該數(shù)據(jù)類(lèi)型明確的情況下進(jìn)行(如將Object型轉(zhuǎn)換為String型);若類(lèi)型不一致,編譯器在編譯過(guò)程中不會(huì)報(bào)錯(cuò),但在運(yùn)行時(shí)會(huì)出錯(cuò)
額外說(shuō)明: List能否轉(zhuǎn)為L(zhǎng)ist?
不能。具體描述如下:

// 代碼1和代碼2相同 // 代碼1 List<String> strings = new LinkedList<String>( ); List<Integer> ints = new LinkedList<Integer>( ); // 代碼2 List strings = new LinkedList( ); List ints = new LinkedList( ); // 轉(zhuǎn)換方式可以是如下: List ss=strings; List<Object> objects=ss;
總結(jié)
本篇片文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
springboot + mybatis + druid + 多數(shù)據(jù)源的問(wèn)題詳解
這篇文章主要介紹了springboot + mybatis + druid + 多數(shù)據(jù)源的問(wèn)題詳解,示例代碼文字相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
Java中final關(guān)鍵字和final的4種用法
這篇文章主要給大家分享的是?Java中final關(guān)鍵字和final的4種用法修飾類(lèi)、修飾方法、修飾變量、修飾參數(shù),下面文章具有一定的參考價(jià)值,需要的小伙伴可以參考一下2021-11-11
Java并發(fā)LinkedBlockingQueue源碼分析
這篇文章主要為大家介紹了Java并發(fā)LinkedBlockingQueue源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Linux下Java開(kāi)發(fā)環(huán)境搭建以及第一個(gè)HelloWorld
這篇文章主要介紹了Linux下Java開(kāi)發(fā)環(huán)境搭建以及第一個(gè)HelloWorld的實(shí)現(xiàn)過(guò)程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-09-09
springboot定時(shí)任務(wù)SchedulingConfigurer異步多線程實(shí)現(xiàn)方式
這篇文章主要介紹了springboot定時(shí)任務(wù)SchedulingConfigurer異步多線程實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
Swagger3.0 整合spring boot2.7x避免swagger2.0與boot2.7沖突
這篇文章主要介紹了Swagger3.0 整合spring boot2.7x避免swagger2.0與boot2.7沖突問(wèn)題,通過(guò)注釋掉2.0引入的倆包,直接引入3.0,文中結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-10-10

