教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

Java培訓(xùn)之通配符

更新時(shí)間:2016年06月28日14時(shí)13分 來源:傳智播客Java培訓(xùn)學(xué)院 瀏覽次數(shù):

1 通配符的作用
Object[] objs = new String[10];
objs[0] = new Integer(100);
上面代碼編譯是可以通過的,但在運(yùn)行時(shí)會(huì)出現(xiàn)ArrayStoreException。因?yàn)閛bjs數(shù)組真實(shí)的身份是String[],向String[]數(shù)組中存放Integer對象當(dāng)然是不行的。
ArrayList<Object> list = new ArrayList<String>();
list.add(new Integer(100);
上面代碼在第一行位置編譯失敗,因?yàn)榉盒透揪筒蛔尠袮rrayList<String>賦值給ArrayList<Object>,對于ArrayList<Object>而言,只能賦值A(chǔ)rrayList<Object>,其他的什么都不能賦值。
這也說明一個(gè)問題:
public static void printList(List<Object> list) {…}
調(diào)用printList()方法只能傳遞給它List<Object>類型的參數(shù),而不能傳遞List<String>,或者List<Integer>,這說明我們的printList()方法有很多的限制,不夠通用?。?!你可能會(huì)想我再重載幾次printList()方法吧,但這是行不通的!
public static void printList(List<Object> list) {…}
public static void printList(List<String> list) {…}
因?yàn)镴VM不知道什么是泛型,這兩個(gè)方法在到了JVM那里時(shí)都是會(huì)把泛型參數(shù)擦除,這兩個(gè)方法就是相同的方法了,擦除之后即:
public static void printList(List list) {…}
public static void printList(List list) {…}
當(dāng)然JVM不可能看到這樣的代碼,因?yàn)榫幾g器不能讓你編譯通過!
處理這個(gè)問題需要使用通配符!

 
2 子類型通配符
public static void printList(List<? extends Person> list) {…}
這回可以傳遞給printList()方法List<Student>,以及List<Teacher>參數(shù)了。只要類型參數(shù)為Person,或者是Person子類型就都可以。
你可以這樣來理解通配符,通配符表示“不知道”的意思。即一個(gè)問號!但子類型通配符還是知道一些信息的,它只知道用戶轉(zhuǎn)遞的類型參數(shù)一定是Person的子類型。雖然使用了通配符之后printList()方法更加通用了,但是這也是要付出一些代價(jià)的。因?yàn)椴恢繪ist中類型參數(shù)的真實(shí)類型,所以就不能調(diào)用list的add()方法了。你可能會(huì)想add(new Student())應(yīng)該是可以的,但如果List是List<Teacher>呢,你怎么向這樣的List添加Student呢?再想一想,add()方法已經(jīng)作廢了,什么都傳遞不了。
 

3 父類型通配符
public static void printList(List<? super Student> list) {…}
可以傳遞給printList()方法List<Student>,以及List<Person>,甚至List<Object>也是可以的。只要傳遞給printList()方法的List類型參數(shù)為Student,或者Student的父類型就是可以的。
你現(xiàn)在可以向list中添加Student類型的參數(shù),例如:list.add(new Student())。因?yàn)橛脩籼峁┑膮?shù)List<Student>、List<Person>、List<Object>,無論哪一種類型,對于list.add(new Student())都是合法的。
但是,現(xiàn)在我們不知道list的get()方法返回的是什么了!因?yàn)橛脩魝鬟f的可能是List<Student>、List<Person>、List<Object>,如果我們用Student s = list.get(0),那么如果list其實(shí)是一個(gè)List<Person>豈不是出錯(cuò)了!沒錯(cuò),只能使用Object來接收list.get(0)的返回值了。
 

4 無界通配符
所謂無界通配符,即List<?>,對通配符沒有限定。你可以給List<?>賦任意的值,但是,你能使用這樣的list干什么呢?也不能add(),也只能使用Object來接收get()方法返回值。
所以,通常List<?>只能表示你在使用泛型而已!編譯器會(huì)認(rèn)為List<?>比List更加優(yōu)雅一些!你可能也看出來了,泛型還真是很垃圾?。?!這也是沒有辦法中的辦法,現(xiàn)在的泛型是遷移性兼容的一種版本而已!Java設(shè)計(jì)者不敢讓JVM知道泛型的存在,原因是為了兼容1.4之前的版本。當(dāng)所有人都在使用1.5以上版本的JDK后,Java的泛型可能就不會(huì)再是編譯期狀態(tài)了。
 

本文版權(quán)歸傳智播客Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:傳智播客Java培訓(xùn)學(xué)院
首發(fā):http://metathetuscanyresort.com/javaee
0 分享到:
和我們在線交談!