Java泛型及類型校驗(yàn)的應(yīng)用
泛型是什么
- 泛型(Generics)是編程語(yǔ)言中的一種類型參數(shù)化機(jī)制,它允許在定義類、接口或方法時(shí)使用類型參數(shù)。這些類型參數(shù)可以在實(shí)際使用時(shí)被具體的類型所替換,從而實(shí)現(xiàn)代碼的復(fù)用性和靈活性。通過(guò)泛型,可以編寫更加通用的組件,同時(shí)保持類型安全。
引入
- 在實(shí)際的需求中,我們可能會(huì)遇見(jiàn)需要接收一個(gè)參數(shù)但是參數(shù)的類型不能確定,最簡(jiǎn)單的方法就是定義多個(gè)類型成員變量, 但隨著接收參數(shù)的類型增加,去類中創(chuàng)建多個(gè)成員變量就會(huì)顯得很麻煩,比如:當(dāng)data變量可能為整型、浮點(diǎn)型、布爾型、字符型、字符串型的任何一種,總不能都去創(chuàng)建一個(gè)該類型的data成員變量吧,這時(shí)候就需要使用泛型了
泛型的應(yīng)用
泛型在類中的應(yīng)用
- 如下方代碼所示,我們使用了
<T>給該類指定了一個(gè)需要接收的參數(shù),這個(gè)參數(shù)實(shí)際上要接收的是一個(gè)類型值。這就是泛型參數(shù),而后面的屬性的類型,方法參數(shù)的類型就是由參數(shù)T來(lái)決定的:
package com.generic;
//public class Box{
public class Box<T>{
// private int data;
private T data;
// private String data;
//public void setData(int data) {
// this.data = data; }
public void setData(T data) {
this.data = data;
}
//public int getData() {
// return data;
//}
public T getData() {
System.out.println("data類型是:" + this.data.getClass());
return data;
}
}- 我們?cè)贕enericMain類中使用Box類,我們先指定Box的類型,在創(chuàng)建Box的對(duì)象,如下方代碼所示:
public class GenericMain {
public static void main(String[] args){
Box <boxInter> = new Box<>();
boxInter.setData(9);
Box<String> boxString = new Box<>();
boxString.setData("Hello World");
//測(cè)試用例:
int data = boxInter.getData();
System.out.println("data的值是:" + data);
String dataStr = boxString.getData();
System.out.println("data的值是" + dataStr);
//輸出案例:
//data類型是:class java.lang.Integer
//data的值是:9
//data類型是:class java.lang.String
//data的值是Hello World
}
}- 拓展:實(shí)際上我們平時(shí)使用的ArrayList容器就是利用率泛型來(lái)成為不同類型的容器,即為先指定類型后創(chuàng)建與類型匹配的對(duì)象,可以按住
ctrl+右擊查看ArrayList的源碼,會(huì)發(fā)現(xiàn)實(shí)際上ArrayList的源碼中也有一個(gè)泛型參數(shù)<E>
//ArrayList的源碼開(kāi)頭
public class ArrayList<E> extends AbstractList<E>{ ... 泛型在接口的應(yīng)用(多態(tài)--類型校驗(yàn))
- 可以創(chuàng)建一個(gè)接口,該接口用于實(shí)現(xiàn),根據(jù)不同的類型,進(jìn)行不同的輸出,如下方代碼所示:
- 創(chuàng)建一個(gè)擁有泛型參數(shù)的接口,在接口中創(chuàng)建一個(gè)抽象方法
- 抽象方法中指定傳入?yún)?shù)的類型由泛型決定
public interface Printtable<T> {
void print(T data);
}- 創(chuàng)建實(shí)現(xiàn)接口的類
- 先創(chuàng)建一個(gè)指定類型為Integer的類
package com.generic; //定義類來(lái)實(shí)現(xiàn)接口 //public class IntegerPrinttable implements Printtable{ //我們還需要指定處理泛型中的哪種類型,這樣寫的好處是java會(huì)幫我們做類型檢查, //使用接口的對(duì)象的泛型該實(shí)現(xiàn)類的泛型是否匹配 public class IntegerPrinttable implements Printtable<Integer>{ // @Override // public void print(Object data) { } @Override public void print(Integer data) { System.out.println("我被用于指定輸出Interger類型的參數(shù)" + data); // 提供接口中的抽象方法的具體實(shí)現(xiàn) } }- 創(chuàng)建一個(gè)類來(lái)實(shí)現(xiàn)接口,指定類型為String
package com.generic; //定義類來(lái)實(shí)現(xiàn)接口 public class StringPrinttable implements Printtable<String>{ // 提供接口中的抽象方法的具體實(shí)現(xiàn) @Override public void print(String data) { System.out.println("我被用于指定輸出String類型的參數(shù)" + data); } } - 在Box類中使用接口
- 為了使用接口,可以先創(chuàng)建一個(gè)接口的引用
private Printtable<T> printtable; - 創(chuàng)建一個(gè)使用該接口的方法printData(直接調(diào)用接口的引用拿到的對(duì)象中的print方法);
- 最后我們寫一個(gè)Box的構(gòu)造方法,形式參數(shù)為
Printtable<T> printtable,即為接口的引用,但需注意的是,這里的目的不是傳入接口對(duì)象(接口本身也不能實(shí)例化為對(duì)象),而是利用向上轉(zhuǎn)型(父類持有子類對(duì)象)持有實(shí)現(xiàn)類的對(duì)象,利用向上轉(zhuǎn)型的特性,實(shí)現(xiàn)多態(tài)
public class Box<T>{ private T data; private Printtable<T> printtable; //在類中將接口聲明,可以看為,我們需要在這個(gè)類中使用該接口的實(shí)現(xiàn) public Box(Printtable<T> printtable) { this.printtable = printtable; //這里傳入實(shí)現(xiàn)了printtable接口類的對(duì)象,這里實(shí)際上是向上轉(zhuǎn)型 //這里的目的實(shí)際上就是在使用print方法時(shí)通過(guò)接口選擇那種print方法 } public void setData(T data) { this.data = data; } public T getData() { System.out.println("data類型是:" + this.data.getClass()); System.out.println(this.data); return data; } public void printData() { printtable.print(this.data); //這里我們使用實(shí)現(xiàn)了接口的類的對(duì)象中的方法 } } - 為了使用接口,可以先創(chuàng)建一個(gè)接口的引用
- 在主類GenericMain中進(jìn)行測(cè)試
- 在Box類中我們寫了構(gòu)造方法要求像傳入一個(gè)接口實(shí)現(xiàn)類的對(duì)象,至于具體傳入哪個(gè)則是根據(jù)Box對(duì)象選擇了泛型的哪一種來(lái)決定的
- 之后就可以調(diào)用box中的方法了
- 我們分別調(diào)用
boxInter.printData(); boxString.printData();,printData會(huì)根據(jù)父類接口持有的類對(duì)象,匹配實(shí)現(xiàn)接口的子類的對(duì)象中的方法
public class GenericMain { public static void main(String[] args){ //創(chuàng)建容器容器中添加元素 Box<Integer> boxInter = new Box<>(new IntegerPrinttable()); boxInter.setData(9); //創(chuàng)建容器容器中添加元素 Box<String> boxString = new Box<>(new StringPrinttable()); boxString.setData("Hello World"); //測(cè)試用例: boxInter.printData(); boxString.printData(); //輸出案例: /* 我被用于指定輸出Interger類型的參數(shù)9 我被用于指定輸出String類型的參數(shù)Hello World */ } } - 泛型在接口中的應(yīng)用的例子中,即體現(xiàn)了面向?qū)ο蟮亩鄳B(tài)特性,又體現(xiàn)了泛型能夠進(jìn)行類型校驗(yàn)的功能,在創(chuàng)建box對(duì)象的時(shí)候,使用的先指定類型,后創(chuàng)建與指定類型匹配的對(duì)象
- 在上面的例子中,我們可以試著創(chuàng)建不匹配指定泛型的接口實(shí)現(xiàn)類對(duì)象,可以發(fā)現(xiàn)因?yàn)轭愋筒黄ヅ鋓de給我們標(biāo)紅報(bào)錯(cuò)了

- 因?yàn)槲覀儽緫?yīng)給
Printtable<String> printtable賦值public class StringPrinttable implements Printtable<String>,即為父類接口未持有匹配的子實(shí)現(xiàn)類
- 在上面的例子中,我們可以試著創(chuàng)建不匹配指定泛型的接口實(shí)現(xiàn)類對(duì)象,可以發(fā)現(xiàn)因?yàn)轭愋筒黄ヅ鋓de給我們標(biāo)紅報(bào)錯(cuò)了
泛型在方法中的應(yīng)用
- 創(chuàng)建一個(gè)方法,如下方代碼所示
public static<T> void printList(ArrayList<T> list){
for(T data:list){
System.out.println(data);
}
}- 調(diào)用方法,如下方代碼所示
- 在這里不需要給
public static<T> void printList(ArrayList<T> list)傳單獨(dú)的類型給泛型,因?yàn)樵趐rintList方法的原型中只要求傳入ArrayList的對(duì)象,而對(duì)象中就已經(jīng)指定了泛型的類型了
- 在這里不需要給
public static void main(String[] args){
//列表泛型方法測(cè)試用例是
ArrayList<Integer> list = new ArrayList<>();
list.add(9);
list.add(8);
list.add(7);
printList(list);
//這里String會(huì)被當(dāng)作泛型T的值直接傳入
}到此這篇關(guān)于Java泛型及類型校驗(yàn)的文章就介紹到這了,更多相關(guān)Java類型校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java工具類實(shí)現(xiàn)文件壓縮zip以及解壓縮功能
這篇文章主要給大家介紹了關(guān)于java工具類實(shí)現(xiàn)文件壓縮zip以及解壓縮功能的相關(guān)資料,文中主要使用使用的是hutool工具類,Hutool是一個(gè)Java工具類庫(kù),由國(guó)內(nèi)的程序員loolly開(kāi)發(fā),目的是提供一些方便、快捷、實(shí)用的工具類和工具方法,需要的朋友可以參考下2024-02-02
淺談java中String StringBuffer StringBuilder的區(qū)別
下面小編就為大家?guī)?lái)一篇淺談java中String StringBuffer StringBuilder的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06
JAVA導(dǎo)出EXCEL表格的實(shí)例教學(xué)
在本文中我們給大家整理了關(guān)于JAVA導(dǎo)出EXCEL表格的實(shí)例教學(xué)以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-02-02
Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn)
這篇文章主要介紹了Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Java微信公眾平臺(tái)開(kāi)發(fā)(12) 微信用戶信息的獲取
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開(kāi)發(fā)第十二步,微信用戶信息的獲取,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
SpringBoot編譯target目錄下沒(méi)有resource下的文件踩坑記錄
這篇文章主要介紹了SpringBoot編譯target目錄下沒(méi)有resource下的文件踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08

