1. 程式人生 > >理解Java泛型 通配符 ? 以及其使用

理解Java泛型 通配符 ? 以及其使用

結構 及其 對象 col () 引用變量 .get pub 同時

什麽是泛型:

泛型從字面上理解,是指一個類、接口或方法支持多種類型,使之廣泛化、一般化和更加通用。Java中使用Object類來定義類型也 能實現泛型,但缺點是造成原類型信息的丟失,在使用中容易造成ClassCastException。

Java泛型帶到的好處:

  1. 使得一個類或方法中的類型參數化,最終達到代碼復用的效果。( 不使用泛型,你可能需要每種情況的類或方法都要定義一遍 )
  2. 實現類型檢查的功能,避免ClassCastException。(這是相對於使用Object類型實現泛型而言。因為我可以每個類都定義一遍來實現所謂的類型檢查。)

泛型自定義:類、接口、方法

//定義泛型類,接口的定義和類一樣
class G1<T> { T content; } // 定義泛型方法,方法的頭部使用<T>聲明,註意結構 class GMethod1 { // 一般泛型方法定義 public static <T> void method1(T params) { } // 返回值也為泛型 public static <E> E method2(E params) { E content = params; return content; } } // extends 的使用,限定泛型的範圍,等於或者是extends的子類
class G2<T extends Number> { T content; }

泛型的使用

    //泛型類或接口的使用
    List<String> list = new ArrayList<>();

    //泛型方法的使用,在方法前面使用<>傳入類型
    <String>gMethod1.method1("str");
    <Integer>gMethod1.method1(new Integer(1));

    //如果入參的參數中使用了T,則可以省略方法前面的<>,編譯器可以自行識別出其類型
gMethod1.method1("str"); gMethod1.method1(new Integer(1));

通配符?

什麽時候會用通配符:

通配符只有在修飾一個變量時會用到,使用它可方便地引用包含了多種類型的泛型;

    public static void main() {

        //不使用通配符
        ArrayList<Object> arr = new ArrayList<Object>();
        // ArrayList<Object> arr = new ArrayList<String>(); 編譯不通過,arr只能引用包含Object的集合

        //使用通配符
        ArrayList<?> arr2;
        arr2 = new ArrayList<String>();
        arr2 = new ArrayList<Integer>();
        arr2.get(0);    //返回的,是一個Object對象,通配符會使原集合包含類型信息丟失,也是通配符的使用代價

    // 通常在方法參數中才會使用通配符,使得這個方法可以引用多種泛型集合。這個和範型方法不一樣,這裏只是一個引用變量
    void gMethod(ArrayList<? extends Number> param) {
    }

可以看到,通配符使用方便的同時,使原集合包含類型信息丟失。

通配符的extends super關鍵字

定義泛型中的extend概念完全不一樣,這裏有它自己的含義

        ArrayList<? extends Number> arr3; // Number 是 Integer、Float的父類
        arr3 = new ArrayList<Integer>();
        arr3 = new ArrayList<Float>();
        // arr3 = new ArrayList<String>(); 編譯不通過,String 和 Number不存在繼承關系

        arr3.get(0);    //返回的,是一個Number對象
        arr3.add(null); //使用過通配符修飾的集合變量,只能add(null),因為這個集合中包含的類型已經確定,只是類型信息已經丟失了,add(Object)也不行

擴展:不使用泛型的變量和另一種方式

        //這樣使用功能和通配符一樣,可以多種引用,但一般不推薦這樣使用
        ArrayList a4;
        a4 = new ArrayList<String>();
        a4 = new ArrayList<Integer>();
        a4.add(new Integer(1));
        a4.add(new String("str"));//和通配符引用不能add不一樣,這樣方式可以add多種類型元素,但一般不推薦

        a4.get(0);  //返回的,是一個Object對象

理解Java泛型 通配符 ? 以及其使用