1. 程式人生 > 實用技巧 >Java泛型<T> T與T的用法

Java泛型<T> T與T的用法

泛型(Generic type 或者 generics)是對 Java 語言的型別系統的一種擴充套件,以支援建立可以按型別進行引數化的類。可以把型別引數看作是使用引數化型別時指定的型別的一個佔位符,就像方法的形式引數是執行時傳遞的值的佔位符一樣。 在集合框架(Collection framework)中泛型的身影隨處可見。例如,Map 類允許向一個 Map 型別的例項新增任意類的物件,即使最常見的情況在給定對映(map)中儲存一個string鍵值對。

命名型別引數

對於常見的泛型模式,推薦的泛型型別變數:
    1. E:元素(Element),多用於java集合框架
    2. K:關鍵字(Key)
    3. N:數字(Number)
    4. T:型別(Type)
    5. V:值(Value)
大家都知道,Java的泛型是偽泛型,這是因為Java在編譯期間,所有的泛型資訊都會被擦除,正確理解泛型概念的首要前提是理解型別擦除。Java 泛型是如何工作的?什麼是型別擦除?答:泛型是通過型別擦除來實現的,編譯器在編譯時擦除了所有泛型型別相關的資訊,所以在執行時不存在任何泛型型別相關的資訊,譬如 List<Integer> 在執行時僅用一個 List 來表示,這樣做的動機是相容 Java 1.5 之前版本。 泛型擦除具體來說就是在編譯成位元組碼時首先進行型別檢查,然後進行型別擦除(即所有型別引數都用他們的限定型別替換,包括類、變數和方法),最後如果型別擦除和多型性發生衝突,就在子類中使用橋接方法解決;如果呼叫泛型方法的返回型別被擦除,則在呼叫該方法時插入強制型別轉換。
在型別擦除中,編譯器確保不會建立額外的類,並且沒有執行時開銷。

型別擦除原則

  1. 用通用型別的型別引數替換其繫結的有界型別引數;
  2. 如果使用無界型別引數,則使用Object替換型別引數;
  3. 插入型別轉換以實現型別安全;
  4. 生成橋接方法以在擴充套件通用型別中保持多型。
<T> T和T的區別T是Type的首字母縮寫;<T> T 表示“返回值”是一個泛型,傳入什麼型別,就返回什麼型別;而單獨的“T”表示限制傳入的引數型別。

<T> T 的用法

這個<T> T表示返回值T的型別是泛型,T是一個佔位符,用來告訴編譯器,這個東西是先給我留著, 等我編譯的時候再告訴你是什麼型別。
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
public class Demo {
    public static void main(String[] args) {
        Demo demo = new Demo();
        //獲取string型別
        List<String> array = new ArrayList<String>();
        array.add("test");
        array.add("doub");
        String str = demo.getListFisrt(array);
        System.out.println(str);
        //獲取Integer型別
        List<Integer> nums = new ArrayList<Integer>();
        nums.add(31);
        nums.add(32);
        Integer num = demo.getListFisrt(nums);
        System.out.println(num);
    }

    /**
     * 這個<T> T 可以傳入任何型別的List
     * 關於引數T
     * 第一個 表示是泛型
     * 第二個 表示返回的是T型別的資料
     * 第三個 限制引數型別為T
     *
     * @param data
     * @return
     */
    private <T> T getListFisrt(List<T> data) {
        if (CollectionUtils.isEmpty(data)) {
            return null;
        }
        return data.get(0);
    }
}

T 的用法

單獨的T表示限制引數的型別。這種用法一般多用於共同操作一個類物件,然後獲取裡面的集合資訊。

import java.util.ArrayList;
import java.util.List;

public class Demo2<T> {

    public static void main(String[] args) {
        //限制T 為String 型別
        Demo2<String> demo = new Demo2<String>();
        List<String> array = new ArrayList<String>();
        array.add("Tom");
        array.add("河南");
        String str = demo.getListFisrt(array);
        System.out.println(str);

        //獲取Integer型別
        Demo2<Integer> demo2 = new Demo2<Integer>();
        List<Integer> nums = new ArrayList<Integer>();
        nums.add(12);
        nums.add(13);
        Integer num = demo2.getListFisrt(nums);
        System.out.println(num);
    }

    /**
     * 這個只能傳遞T型別的資料
     * 返回值 就是Demo<T> 例項化傳遞的物件型別
     *
     * @param data
     * @return
     */
    private T getListFisrt(List<T> data) {
        if (data == null || data.size() == 0) {
            return null;
        }
        return data.get(0);
    }
}

Reference

https://www.cnblogs.com/jpfss/p/9929108.html