Java泛型

1.先解釋下泛型概念

泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操做的數據類型被指定爲一個參數。這種參數類型能夠用在類、接口和方法的建立匯中,分別稱爲泛型類、泛型接口、泛型方法。Java語言引入泛型的好處是安全簡單java

在Java SE 1.5以前,沒有泛型的狀況下,經過對類型Object的引用來實現參數的"任意化""任意化"帶來的缺點是要作顯式的強制類型轉換,而這種轉換是要求開發者對實際參數類型能夠預知的狀況下進行的對於強制類型轉換錯誤的狀況,編譯器可能不提示錯誤,在運行的時候纔出現異常,這是一個安全隱患安全

泛型的好處是在編譯的時候檢查類型安全,而且全部的強制轉換都是自動和隱式的,以提升代碼的重用率app

舉個例子:Box類定義爲一個泛型類:ide

public class Box<T> {

    private T object;

    public void set(T object) {
        this.object = object;
    }

    public T get(){
        return this.object;
    }
}

建立一個Box對象,不帶泛型參數,發現獲取對象的時候須要強制轉換this

public class Test {

    public static void main(String[] args){
        //建立一個Box對象,不帶泛型參數,發現獲取對象的時候須要強制轉換
        Box box = new Box();
        box.set(new Apple());
        Apple apple = (Apple) box.get();
    }

}

建立一個Box對象,帶泛型參數,獲取對象的時候就不須要強制轉換code

public class Test {

    public static void main(String[] args){
        //建立一個Box對象,帶泛型參數,獲取對象的時候就不須要強制轉換
        Box<Apple> box = new Box<Apple>();
        box.set(new Apple());
        Apple apple = box.get();
    }

}

總結下泛型的好處就是 省去了強制轉換,能夠在編譯時候檢查類型安全,能夠用在類,方法,接口上對象

可是咱們定義泛型類,泛型方法,泛型接口的時候常常會遇見不少不一樣的通配符T,E,K,V等等,這些通配符又都是什麼意思呢?繼續往下看接口

2. 下面說說泛型通配符T,E,K,V的區別

這些全都屬於java泛型的通配符,剛開始我看到這麼多通配符,一下暈了,這幾個其實沒什麼區別,只不過是一個約定的代碼,也就是說element

使用大寫字母A,B,C,D....X,Y,Z定義的,就都是泛型把T換成A也同樣,這裏T只是名字上的意義而已開發

  • ?表示不肯定的java類型
  • T(type)表示具體的一個java類型
  • K V(key value)分別表明java鍵值中的key value)分別表明java鍵值中的key
  • E(element)表明Element,通常用來表示集合類型中的元素的類型,例如List接口的定義,public interface List <E> extends Collection <E>

舉個例子

public class Test<T> {

    public List<T> list = new ArrayList<T>();
    public static void main(String[] args){
        Test<String> test = new Test<String>();
        test.list.add("hello");
        System.out.println(test.list);
    }

}

public class Test<A> {

    public List<A> list = new ArrayList<A>();
    public static void main(String[] args){
        Test<String> test = new Test<String>();
        test.list.add("hello");
        System.out.println(test.list);
    }

}

將T換成了A,在執行效果上是沒有任何區別的只不過咱們約定好了T表明type,因此仍是按照約定規範來比較好,增長了代碼的可讀性。

若是要定義多個泛型參數,好比說;兩個泛型參數,很典型的一個例子是Map的key,value泛型,咱們也能夠定義一個這樣的

public interface MyMap<K,V> {

    public K getKey();
    public V getValue();
}
public class MyMapImpl<K,V> implements MyMap<K,V> {

    private K key;
    private V value;

    public MyMapImpl(K key,V value){
        this.key = key;
        this.value = value;
    }

    @Override
    public K getKey() {
        return null;
    }

    @Override
    public V getValue() {
        return null;
    }
}

這樣就能夠傳入任意類型,建立實例了,不用轉換類型

public class Test{

    public static void main(String[] args){
        MyMap<String, Integer> mp1= new MyMapImpl<String, Integer>("Even", 8);
        MyMap<String, String> mp2= new MyMapImpl<String, String>("hello", "world");
        MyMap<Integer, Integer> mp3= new MyMapImpl<Integer, Integer>(888, 888);
    }

}

若是要定義超過兩個,三個或者三個以上的泛型參數可使用T1,T2,....Tn,像這樣子

public class Test<T1,T2,T3>{

    public static void main(String[] args){
    }

    public void print(T1 t1,T2 t2,T3 t3){
        System.out.println(t1.getClass());
        System.out.println(t2.getClass());
        System.out.println(t3.getClass());
    }

}

3. 接下來講說List<T>,List<Object>,List<?>區別

泛型三種:

  1. ArrayList<T> al = new ArrayList<T>();指定集合元素只能是T類型。
  1. ArrayList<?> al = new ArrayList<?>(); 集合元素能夠是任意類型,這種沒有意義,通常是方法中,只是爲了說明用法。
  2. ArrayList<? extends E> al = new ArrayList<? extends E>(); 泛型的限定:? extends E:接收E類型或者E的子類型。? super E:接收E類型或者E的父類型。
  3. Object和T不一樣點在於,Object是一個實打實的類,並無泛指誰,而T能夠泛指Object,比方public void printList(List<T> list){}方法中能夠傳入List<Object> list類型參數,也能夠傳入List<String> list類型參數,可是public void printList(List<Object> list){}就只能傳入List<Object> list類型參數,由於Object類型並無泛指誰,是一個肯定的類型。

4. 最後來講說T,Class<T>,Class<?>區別

T是一種具體的類,例如String,List,Map...等等,這些都是屬於具體的類,這個比較好理解。Class是什麼呢,Class也是一個類,但Class是存放上面String,List,Map...類信息的一個類,有點抽象,咱們一步一步來看。

相關文章
相關標籤/搜索