Java中的泛型詳細(xì)解析
引言
使用傳統(tǒng)方法的問題分析
1.不能對(duì)加入到集合ArrayList中的數(shù)據(jù)類型進(jìn)行約束(不安全)
2.遍歷的時(shí)候需要進(jìn)行類型轉(zhuǎn)換,如果集合中的數(shù)據(jù)量較大,對(duì)效率有影響
泛型的好處
1.編譯時(shí)會(huì)檢查添加元素的類型,提高了安全性
2.減少了類型轉(zhuǎn)換的次數(shù),提高效率
3.不再提示編譯警告
一、泛型介紹
泛(廣泛)型(類型)
1.泛型又稱參數(shù)化類型,是JDK5.0出現(xiàn)的新特性,解決了數(shù)據(jù)類型的安全型問題
2.在類聲明或?qū)嵗瘯r(shí)只要指定好需要的具體類型即可
3.Java泛型可以保證如果程序在編譯時(shí)沒用發(fā)出警告,運(yùn)行時(shí)就不會(huì)產(chǎn)生ClassCastException異常。同時(shí),代碼更加簡(jiǎn)潔、健壯
4.泛型的作用是:可以在類聲明時(shí)通過一個(gè)標(biāo)識(shí)表示類中某個(gè)屬性的類型,或者是某個(gè)方法的返回值的類型,或者是參數(shù)類型
二、泛型的語法
2.1 泛型的聲明
- class 類<K,V> { }
- interface 接口<T> { }
說明:1.其中的K,V,T不代表值,而是表示類型; 2.任意字母都可以,常用T表示,是Type的縮寫
2.2 泛型的實(shí)例化
要在類名后面指定類型參數(shù)的值(類型)
1. List<String> strList = new ArrayList<String>();
2. Iterator<Customer> iterator = customers.iterator();
三、泛型使用的注意事項(xiàng)和細(xì)節(jié)
1.給泛型指向數(shù)據(jù)類型時(shí),要求是引用類型,不能是基本數(shù)據(jù)類型
2.在給泛型指定具體類型后,可以傳入該類型或者其子類類型
3.泛型使用形式
①List <Integer> list1 = new ArrayList<Integer>();
②List <Integer> list2 = new ArrayList<>();
③如果這樣寫 List list3 = new ArrayList();默認(rèn)給它的泛型是Object
四、自定義泛型
4.1 基本語法
class 類名<T,R...> { //...表示可以有多個(gè)泛型
成員
}4.2 注意細(xì)節(jié)
1.普通成員可以使用泛型(屬性、方法)
2.使用泛型的數(shù)組不能初始化
3.靜態(tài)方法中不能使用類的泛型
4.泛型類的類型,是在創(chuàng)建對(duì)象時(shí)確定的(因?yàn)閯?chuàng)建對(duì)象時(shí),需要指定確定類型)
5.如果在創(chuàng)建對(duì)象時(shí)沒用指定類型,默認(rèn)為Objcet
4.3 自定義泛型接口
4.3.1 基本語法
interface 接口名 <T,R...> {
}4.3.2 注意細(xì)節(jié)
1.接口中,靜態(tài)成員也不能使用泛型()
2.泛型接口的類型,在繼承接口或者實(shí)現(xiàn)接口時(shí)確定
3.沒有指定類型,默認(rèn)為Object
4.4 自定義泛型方法
4.4.1 基本語法
修飾符 <T,R...>返回類型 方法名(參數(shù)列表) {
}4.4.2 注意細(xì)節(jié)
1.泛型方法可以定義在普通類中,也可以定義在泛型類中
2.當(dāng)泛型方法唄調(diào)用時(shí),類型會(huì)確定
3.pulbic void ear(E e) {} ,修飾符后沒有<T,R...>,eat方法不是泛型方法,而是使用了泛型
public class CustomMethodGeneric {
public static void main(String[] args) {
Car car = new Car();
car.fly("寶馬",100);//當(dāng)調(diào)用方法時(shí)傳入?yún)?shù),編譯器就會(huì)確定類型
Fish<String, ArrayList> fish = new Fish<>();
fish.hello(new ArrayList<>(),1.1f);
}
}
//泛型方法,可以定義在普通類中,也可以定義在泛型類中
class Car { //普通類
public void run() { //普通方法
}
//說明,泛型方法
//1. <T,R>就是泛型
//2. 是提供給fly使用的
public <T,R> void fly(T t, R r) { //泛型方法
System.out.println(t.getClass()); //String
System.out.println(r.getClass()); //Integer
}
}
class Fish<T,R> { //泛型類
public void run() { //普通方法
}
public<U,M> void eat(U u, M m) { //泛型方法
}
//說明
//1.下面的hi方法不是泛型方法
//2.是hi方法使用了類聲明的泛型
public void hi(T t){
}
//泛型方法可以使用類聲明的泛型,也可以使用自己聲明泛型
public<K> void hello(R r,K k){
System.out.println(r.getClass());
System.out.println(k.getClass());
}
}五、泛型的繼承和通配符
通配符:?
1. 泛型不具備繼承性
2. <?> :支持任意泛型類型
泛型的上下限
3. <? extends A> :支持A類以及A類的子類,規(guī)定了泛型的上限
4. <? super A>:支持A類以及A類的父類,不限于直接父類,規(guī)定了泛型的下限
/**
* @author 咕咕貓
* @version 1.0
* 泛型的繼承與通配符
*/
@SuppressWarnings({"all"})
public class GenericExtends {
public static void main(String[] args) {
Object o = new String("XXX");
//泛型沒有繼承性
//List<Object> list = new ArrayList<String>();
//舉例說明下面三個(gè)方法的使用
List<Object> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<AA> list3 = new ArrayList<>();
List<BB> list4 = new ArrayList<>();
List<CC> list5 = new ArrayList<>();
//如果是 List<?> c ,可以接受任意的泛型類型
printCollection1(list1);
printCollection1(list2);
printCollection1(list3);
printCollection1(list4);
printCollection1(list5);
//List<? extends AA> c: 表示 上限,可以接受 AA 或者 AA 子類
// printCollection2(list1);//×
// printCollection2(list2);//×
printCollection2(list3);//√
printCollection2(list4);//√
printCollection2(list5);//√
//List<? super AA> c: 支持 AA 類以及 AA 類的父類,不限于直接父類
printCollection3(list1);//√
//printCollection3(list2);//×
printCollection3(list3);//√
//printCollection3(list4);//×
//printCollection3(list5);//×
}
//說明: List<?> 表示 任意的泛型類型都可以接受
public static void printCollection1(List<?> c) {
for (Object object : c) { // 通配符,取出時(shí),就是 Object
System.out.println(object);
}
}
// ? extends AA 表示 上限,可以接受 AA 或者 AA 子類
public static void printCollection2(List<? extends AA> c) {
for (Object object : c) {
System.out.println(object);
}
}
// ? super 子類類名 AA:支持 AA 類以及 AA 類的父類,不限于直接父類,
//規(guī)定了泛型的下限
public static void printCollection3(List<? super AA> c) {
for (Object object : c) {
System.out.println(object);
}
}
}
class AA {
}
class BB extends AA {
}
class CC extends BB {
}六、JUnit
6.1 為什么需要JUnit
1.一個(gè)類有很多功能代碼需要測(cè)試,為了測(cè)試,就需要寫到main方法中
2.如果 有多個(gè)功能代碼測(cè)試,就需要來回注銷,切換很麻煩
6.2 基本介紹
1.JUnit是一個(gè)Java語言的單元測(cè)試框架
2.多數(shù)Java的開發(fā)環(huán)境都已經(jīng)集成了JUnit作為單元測(cè)試的工具
使用:在需要測(cè)試的代碼前加上@Test,按alt + enter選擇版本即可
到此這篇關(guān)于Java中的泛型詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java泛型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA OutputStreamWriter流的實(shí)現(xiàn)
OutputStreamWriter是從字符流到字節(jié)流的橋接,它使用的字符集可以通過名稱指定,也可以明確指定,或者可以接受平臺(tái)的默認(rèn)字符集,本文詳細(xì)的介紹了JAVA OutputStreamWriter流的使用,感興趣的可以了解一下2021-06-06
Java 向上轉(zhuǎn)型和向下轉(zhuǎn)型的詳解
這篇文章主要介紹了 Java 向上轉(zhuǎn)型和向下轉(zhuǎn)型的詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04
java組件commons-fileupload文件上傳示例
這篇文章主要為大家詳細(xì)介紹了java組件commons-fileupload實(shí)現(xiàn)文件上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
Java深入講解instanceof關(guān)鍵字的使用
instanceof 是 Java 的一個(gè)二元操作符,類似于 ==,>,< 等操作符。instanceof 是 Java 的保留關(guān)鍵字。它的作用是測(cè)試它左邊的對(duì)象是否是它右邊的類的實(shí)例,返回 boolean 的數(shù)據(jù)類型2022-05-05
MyBatis使用logback包打印SQL語句實(shí)踐
文章介紹了如何在Java項(xiàng)目中使用Maven管理依賴,并配置Logback來打印SQL語句,通過修改logback.xml文件,可以將SQL語句以XML格式輸出,便于調(diào)試和分析2026-01-01
shiro實(shí)現(xiàn)單點(diǎn)登錄(一個(gè)用戶同一時(shí)刻只能在一個(gè)地方登錄)
這篇文章主要介紹了shiro實(shí)現(xiàn)單點(diǎn)登錄(一個(gè)用戶同一時(shí)刻只能在一個(gè)地方登錄)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-08-08
log4j2采用AsyncLogger出現(xiàn)的錯(cuò)誤及解決方案
這篇文章主要介紹了log4j2采用AsyncLogger出現(xiàn)的錯(cuò)誤及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java源碼解析HashMap的tableSizeFor函數(shù)
今天小編就為大家分享一篇關(guān)于Java源碼解析HashMap的tableSizeFor函數(shù),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01

