您好,登錄后才能下訂單哦!
這篇文章主要講解了“java泛型中占位符T和?有哪些區別”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java泛型中占位符T和?有哪些區別”吧!
先上兩段代碼:
public static <T> void show1(List<T> list){ for (Object object : list) { System.out.println(object.toString()); } } public static void show2(List<?> list) { for (Object object : list) { System.out.println(object); } }
可以看到show1方法中我們使用了T,大家都知道這是泛型的常見寫法,那么這里的T指的是某一類具體的對象,list集合里只能存放同一類型數據,如果插入不同類型數據則會報錯。
那么show2方法中我們使用的是?,可以看到在void前面并沒有<T>
,?可以表示成占位符,它自己也不知道list集合中會存放多少種類型的數據,所以這樣就表明我們的list中存放N種數據類型也是可以的。
我們通過一段測試代碼來直觀的感受一下二者的區別吧:
public static void test(){ List<Student> list1 = new ArrayList<>(); list1.add(new Student("zhangsan",18,0)); list1.add(new Student("lisi",28,0)); list1.add(new Student("wangwu",24,1)); //這里如果add(new Teacher(...));就會報錯,因為我們已經給List指定了數據類型為Student show1(list1); System.out.println("************分割線**************"); //這里我們并沒有給List指定具體的數據類型,可以存放多種類型數據 List list2 = new ArrayList<>(); list2.add(new Student("zhaoliu",22,1)); list2.add(new Teacher("sunba",30,0)); show2(list2); }
來看看運行結果:
Student{name='zhangsan', age=18, sex=0}
Student{name='lisi', age=28, sex=0}
Student{name='wangwu', age=24, sex=1}
************分割線**************
Student{name='zhaoliu', age=22, sex=1}
Teacher{name='sunba', age=30, sex=0}
從show2方法可以看出和show1的區別了,list2存放了Student和Teacher兩種類型,同樣可以輸出數據,所以這就是T和?的區別啦~小伙伴們了解了吧
下面來看看?的擴展寫法:
List<? extends 數據類型> list
public static void show3(List<? extends Teacher> list) { for (Object object : list) { System.out.println(object); } }
List<? extends Teacher> list
這種寫法表示可以接收Teacher和它的子類數據類型的list集合,寫個測試方法show3(list2);
試試:
Student{name='zhaoliu', age=22, sex=1} Teacher{name='sunba', age=30, sex=0}
可以看到正常輸出,因為集合中的數據都是Teacher的子類類型,如果我們將List<? extends Teacher> list
改成List<? extends Student> list
會出現什么情況?
仔細看這張圖,我們新建了一個list3并且聲明數據類型為Teacher,這個時候調用show3(List<? extends Student> list)
就馬上會報錯的,錯誤信息提示Teacher不能轉換成Student,因為Student是Teacher的子類,而我們只接受Student及它的子類,所以當然會報錯了。
List<? super 數據類型> list
這種寫法表示只接收指定的數據類型及它的父類類型,也簡單的寫段代碼看看效果:
public static void show4(List<? super Student> list) { for (Object object : list) { System.out.println(object); } }
可以看出來,我們接收的是Student及它父類的集合,我們寫兩個集合數據然后調用試試。
List list4 = new ArrayList<>(); list4.add(new Student("sunba",30,0)); list4.add(new Teacher("zhaoliu",22,1)); show4(list4);
在list中插入了一個Student和Teacher對象,看看結果:
Student{name='sunba', age=30, sex=0} Teacher{name='zhaoliu', age=22, sex=1}
沒毛病,正常運行并輸出。
下面我們來看看,如果我們是傳遞的 Student的子類的集合會咋樣
可以看到和之前的一樣,會報錯,理由也是一樣的,以為我們已經定義了只能接收Student及其父類的數據類型。
最后來看一種情況
如果我定義List的時候沒有指定數據類型,并且插入了一個Child,Student,Teacher,還是調用show4(List<? super Student> list)
,會報錯嗎?不會報錯,運行結果又會是什么呢?
可以看到這樣并沒有報錯,因為list可以存放多種數據類型,那么調用show4方法時會是什么結果呢?
可以看到程序正常運行并輸出結果,注意一點,我們接收的是Student及其父類對象數據類型,因為我們的Child是繼承Student的,所以程序自動將我們的Child轉成父類Student進行輸出,所以大家要注意這一點,會自動向上轉化。
感謝各位的閱讀,以上就是“java泛型中占位符T和?有哪些區別”的內容了,經過本文的學習后,相信大家對java泛型中占位符T和?有哪些區別這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。