您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java泛型與包裝類實(shí)例分析的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
泛型的本質(zhì)是為了參數(shù)化類型(在不創(chuàng)建新的類型的情況下,通過泛型指定的不同類型來控制形參具體限制的類型)。
先看以下的例子:
我們以前學(xué)過的數(shù)組,只能存放指定類型的元素。如:int[] array=new int[10];String[] array=new String[10];
而Object類是所有類的父類,那么我們是否可以創(chuàng)建Obj數(shù)組呢?
class Myarray{ public Object[] array=new Object[10]; public void setVal(int pos,Object val){ this.array[pos]=val; } public Object getPos(int pos){ return this.array[pos]; } } public class TestDemo{ public static void main(String[] args) { Myarray myarray=new Myarray(); myarray.setVal(1,0); myarray.setVal(2,"shduie");//字符串也可以存放 String ret=(String)myarray.getPos(2);//雖然我們知道它是字符串類型,但是還是要強(qiáng)制類型轉(zhuǎn)換 System.out.println(ret); } }
以上代碼實(shí)現(xiàn)后,我們發(fā)現(xiàn):
任何類型的數(shù)據(jù)都能存放
2號(hào)下標(biāo)本來就是字符串,但是必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換
以此引出泛型,泛型的目的就是:指定當(dāng)前的容器要持有什么類型的對(duì)象,讓編譯器自己去檢查。
class 泛型類名稱< 類型形參列表>{
//這里可以使用類型參數(shù)
}
泛型的使用:
泛型類<類型實(shí)參> 變量名=new 泛型類<類型實(shí)參>(構(gòu)造方法實(shí)參)
MyArray list=new MyArray<>();
【注】
類型后的<>代表占位符,表示當(dāng)前類是一個(gè)泛型類
在實(shí)例化泛型時(shí),<>中不能是簡單的類型,需要是包裝類
<>不參與泛型的類型組成
不能new泛型類型的數(shù)組
使用泛型不需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換
一個(gè)簡單的泛型:
//此處T可以隨便寫為任意標(biāo)識(shí),常見的如T、E、K、V等形式的參數(shù)常用于表示泛型 //在實(shí)例化泛型類時(shí),必須指定T的具體類型 public class Test<T>{ //key這個(gè)成員變量的類型為T,T的類型由外部指定 private T key; public Test(T key) { //泛型構(gòu)造方法形參key的類型也為T,T的類型由外部指定 this.key = key; } public T getKey(){ //泛型方法getKey的返回值類型為T,T的類型由外部指定 return key; } }
擦除機(jī)制:編譯時(shí)會(huì)將<>中的類型擦除掉,所以<>中的東西不參與類型的組成。會(huì)將T擦除為Object。
為什么不能實(shí)例化泛型類型的數(shù)組?
數(shù)組和泛型之間的一個(gè)重要區(qū)別是它們?nèi)绾螐?qiáng)制執(zhí)行類型檢查。數(shù)組在運(yùn)行時(shí)存儲(chǔ)和檢查類型信息,而泛型是在編譯時(shí)檢查類型錯(cuò)誤。
返回的Object數(shù)組里面,可能存放著任何類型的數(shù)據(jù),如string,通過int類型的數(shù)組來接收,編譯器認(rèn)為是不安全的。
語法:
class 泛型類名稱<T extends 類型邊界>{
}
例:
public class MyArray{} //E只能是Number或Number的子類
public class MyArray<E extends Comparable<E>>{}
//E一定實(shí)現(xiàn)了Comparable接口的類
【注】沒有指定邊界的E,可以看作 E extends Object
? 用于在泛型的使用,即為通配符。通配符用來解決反泛型無法協(xié)變的問題。
如下兩段代碼:
代碼一: public static<T> void printList1(ArrayList<T> list){ for(T x:list){ System.out.println(x); } } 代碼二: public static<T> void printList2(ArrayList<?> list){ for(Object x:list){ System.out.println(x); } }
代碼2中使用了通配符,和代碼1相比,此時(shí)傳入代碼1的具體是什么數(shù)據(jù)類型,我們是不清楚的。
語法:
<? extends 上界>
<? extends Number>//可以傳入的實(shí)參類型為Number或Number的子類
例:對(duì)于以下關(guān)系,我們需要寫一個(gè)方法來打印存儲(chǔ)了Animal或者Animal子類的list。
Animal
Cat extends Animal
Dog extends Animal
代碼一:
public static <t extends Animal> void print1(List<T> list>{ for(T animal:list){ System.out.println(animal);//調(diào)用了T的toString } }
此時(shí)T類型是Animal的子類或自己。
代碼二:通過通配符實(shí)現(xiàn)
public static void print2(List<? extends Animal> list){ for(Animal animal:list){ Syatem.out.println(animal);//調(diào)用了子類的toString方法 } }
兩種代碼的區(qū)別:
對(duì)于泛型實(shí)現(xiàn)的方法來說,<T extends Animal>對(duì)T進(jìn)行了限制,只能是Animal的子類。傳入Cat,就是Cat。
對(duì)于通配符實(shí)現(xiàn)的方法來說,相當(dāng)于對(duì)Animal進(jìn)行了規(guī)定,允許傳入Animal的子類。具體哪個(gè)子類,此時(shí)并不清楚。如:傳入Cat,實(shí)際上聲明的類型是Animal,使用多態(tài)才能調(diào)用Cat的toString方法
通配符上界→父子類關(guān)系:
//需要使用通配符來確定父子類型
MyArrayList<? extends Number>是MyArrayList<Integer>或者M(jìn)yArrayList<Double>的父類
MyArrayList<?>是MyArrayList<? extends Number>的父類
ArrayList<Integer> arrayList1 = new ArrayList<>(); ArrayList<Double> arrayList2 = new ArrayList<>(); List<? extends Number> list = arrayList1; //list.add(1,1);//報(bào)錯(cuò),此時(shí)list的引用的子類對(duì)象有很多,再添加的時(shí)候,任何子類型都可以,為了安全,java不讓這樣進(jìn)行添加操作。 Number a = list.get(0);//可以通過 Integer i = list.get(0);//編譯錯(cuò)誤,只能確定是Number子類
【注】
不能對(duì)其進(jìn)行添加,list中存儲(chǔ)的可能是Number也可能是Number的子類,無法確定類型。
通配符上界適合讀取,不適合寫入。
語法:
<? super 下界>
<? super Integer>//可以傳入的參數(shù)類型是Integer或者Integer的父類
通配符下界的父子類關(guān)系:
MyArrayList<? super Integer>是MyArrayList<Intrger>的父類類型
MyArrayList<?>是MyArrayList<? super Integer>的父類
通配符下界適合寫入元素,不適合讀取。
在Java中,由于基本類型不是繼承自O(shè)bject,為了在泛型中可以支持基本類型,每個(gè)基本類型都對(duì)應(yīng)了一個(gè)包裝類。除了Integer和Character,其余基本類型的包裝類都是首字母大寫。
拆箱和裝箱:
int i=10; //裝箱操作,新建一個(gè)Integer類型對(duì)象,將i的值放入對(duì)象的某個(gè)屬性中 Integer ii=i; //自動(dòng)裝箱 //Integer ii=Integer.valueOf(i); Integer ij= new Integer(i);//顯示裝箱 //拆箱操作,將Integer對(duì)象中的值取出,放到一個(gè)基本數(shù)據(jù)類型中 int j=ii.intValue();//顯示的拆箱 int jj=ii;//隱式的拆箱
以上就是“Java泛型與包裝類實(shí)例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。