首頁 > Java > java教程 > java泛型中佔位符T和?有哪些差別

java泛型中佔位符T和?有哪些差別

王林
發布: 2023-05-11 18:10:06
轉載
1376 人瀏覽過

先上兩段程式碼:

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這種寫法表示可以可以寫法表示可以#List<? extends Teacher> list這個寫法表示可以接收Teacher和它的子類別資料型別的list集合,寫個測試方法show3(list2);

試試:

Student{name=&#39;zhaoliu&#39;, age=22, sex=1}
Teacher{name=&#39;sunba&#39;, age=30, sex=0}
登入後複製
可以看到正常輸出,因為集合中的資料都是Teacher的子類別,如果我們將 List<? extends Teacher> list改成 List list

會出現什麼情況?

java泛型中佔位符T和?有哪些差別

仔細看這張圖,我們新建了一個list3並且宣告資料型別為Teacher,這個時候呼叫show3(List list)

就馬上會報錯的,錯誤訊息提示Teacher不能轉換成Student,因為Student是Teacher的子類,而我們只接受Student及它的子類,所以當然會報錯了。

List 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=&#39;sunba&#39;, age=30, sex=0}
Teacher{name=&#39;zhaoliu&#39;, age=22, sex=1}
登入後複製
沒毛病,正常運作並輸出。

下面我們來看看,如果我們是傳遞的Student的子類別的集合會咋樣

java泛型中佔位符T和?有哪些差別

可以看到和之前的一樣,會報錯,理由也是一樣的,以為我們已經定義了只能接收Student及其父類別的資料型別。

最後來看一種情況

如果我定義List的時候沒有指定資料類型,並且插入了一個Child,Student,Teacher,還是呼叫show4(List super Student> list)

,會報錯嗎?不會報錯,運行結果又會是什麼呢?

java泛型中佔位符T和?有哪些差別

可以看到這樣並沒有報錯,因為list可以存放多種資料類型,那麼呼叫show4方法時會是什麼結果呢?

java泛型中佔位符T和?有哪些差別

可以看到程式正常運作並輸出結果,注意一點,我們接收的是Student及其父類別物件資料類型,因為我們的Child是繼承Student的,所以程式自動將我們的Child轉成父類Student進行輸出,所以大家要注意這一點,會自動向上轉換。 ###

以上是java泛型中佔位符T和?有哪些差別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板