泛型通配符 Generic Wildcards —— ? extends super

Generic Wildcards

1. Upper Bounded Wildcards 上限通配符

  • 上限通配符 upper bounded Wildcards
  • extends關鍵字:在上限通配符中,extends關鍵字是表示通常的意義,它即代表着“繼承”(一個類),也代表着“實現”(一個接口)。

以下述代碼中的List<Person>List<? extends Person>爲例,前者相比受到更多的約束,它只能匹配Person類,而後者除了可以匹配Person類之外,還可以匹配繼承了Person的任意子類

class Person{}

class Man extends Person{}

class Woman extends Person{}

class Children extends Man{}
public class GenericTest {
    public static void main(String[] args) {

//        List<Person> list = new ArrayList<Man>(); //編譯錯誤
        //Man是Person的子類,ArrayList是Person的子類
        //但不代表這ArrayList<Man>是List<Person>的子類


        //使用上限通配符
        //測試:上限是到Person類
        List<? extends Person> list1 = new ArrayList<Person>();
        List<? extends Person> list2 = new ArrayList<Man>();
        List<? extends Person> list3 = new ArrayList<Woman>();
        List<? extends Person> list4 = new ArrayList<Children>();

        //測試:上限是到Man類
//        List<? extends Man> list5 = new ArrayList<Person>();  //報錯,不能是Man的父類
        List<? extends Man> list6 = new ArrayList<Children>();
    }
}

2. Lower Bounded Wildcards 下限通配符

  • 下限通配符 Lower bounded Wildcards
    public static void main(String[] args) {
        List<? super Woman> list = null;

        List<Person> listPerson = new ArrayList<>();
        List<Man> listMan = new ArrayList<>();
        List<Woman> listWoman = new ArrayList<>();
        List<Children> listChildren = new ArrayList<>();

        list = listPerson;
//        list = listMan; //編譯錯誤
        list = listWoman;
//        list = listChildren; //編譯錯誤
    }

3. Unbound Wildcard 無界通配符

  • 無界通配符 Unbound Wildcard 無界通配符使用?指定的類型,例如,List<?>,這被稱爲一個未知類型的List.

    無界通配符的原理是這樣的,以List爲例,它將任意的具體類型List<A>,都看做是List<?>的子類

NOTE

Object類和String類、Double類是繼承關係,但List<Object>List<String>List<Double>不是繼承關係

public void printList(List<Object> list){
    for(Object o : list){
        System.out.print(o+" ");
    }
    System.out.println();
}
@Test
public void test1(){
    List<Double> list1 = new ArrayList<>();
    list1.add(1.0);
    list1.add(3.14);
    list1.add(2.78);
//  printList(list1); //編譯報錯,因爲List<Double>不是List<Object>的子類
}
public void printList(List<?> list){
    for(Object o : list){
        System.out.print(o+" ");
    }
    System.out.println();
}

    @Test
    public void test1(){
        List<Double> list1 = new ArrayList<>();
        list1.add(1.0);
        list1.add(3.14);
        list1.add(2.78);
        printList(list1); 
        /*Output
        1.0 3.14 2.78 
        */
    }

4.參考

https://docs.oracle.com/javase/tutorial/java/generics/index.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章