泛型

《Java編程的邏輯》筆記java

概念和原理

  • 泛型:泛型就是類型參數化,處理的數據類型不是固定的,而是能夠做爲參數傳入。以下編程

    • 泛型類:T表示類型參數。
    public class Pair<T>{
        T first;
        T second;
        public Pair(T first,T second){
            this.first = first;
            this.second = second;
        }
        public T getFirst(){
            return first;
        }
        public T getSecond(){
            return second;
        }
    }
    複製代碼
    • 泛型方法數組

      一個方法是否是泛型的,與它所在的類是否是泛型沒有是什麼關係。安全

      public static <T> int indexoOf(T[] arr,T elm){
          for(int i=0;i<arr.length;i++){
              if(arr[i].equale(elm)){
                  return i;
              }
          }
          return -1;
      }
      // 泛型參數能夠是多個
      public static <U,V> Pair<U,V> makePair(U first,V second){
          Pair<U,V> pair = new Pair<>(first,second);
          return pair;
      }
      // 泛型方法調用時通常不須要特地指定類型參數的實際類型
      makePair(1,"老馬");
      複製代碼
    • 泛型接口this

      // 泛型接口
      public interface Comparable<T> {
          public int compareTo(T o);
      }
      // 實現
      public final class Integer extends Number implements Comparable<Integer>{
          public int compareTo(Integer anotherInteger){
              return compare(this.value,anotherInteger.value);
          }
      }
      複製代碼
  • 基本原理:Java泛型是經過擦除實現的,類定義中的類型參數如T會被替換爲Object,在程序運行過程當中,不知道泛型的實際類型參數,好比Pair,運行中只知道Pair,而不知道Integer。spa

  • 泛型的好處code

    • 更好的安全性
    • 更好的可讀性

類型參數的限定

  • 限定上界:如今咱們知道Java把類型參數,當作Object,但Java支持限定這個參數的上界。參數必須爲給定的上界類型或其子類型,這個限定是經過extends關鍵字類表示的。這個上界能夠是某個具體的類或某個具體接口,也能夠是其餘類型參數。對象

  • 上界爲具體類:接口

    public class NumberPair<U extends Number,V extends Number> extends Pair<U,V>{
        public NumberPair(U first,V second){
            super(first,second);
        }
    }
    //調用
    NumberPair<Integer,Double> pair = new NumberPair<>(10,12.34);
    複製代碼
  • 上界爲某個接口:get

    // T表示一種數據類型,必須實現Comparable接口,且必須能夠與相同類型的元素進行比較
    public static <T extends Comparable<T>> T max(T[] arr){
        T max = arr[0];
        for(int i=1;i<arr.length;i++){
            if(arr[i].compareTo(max)>0){
                max = arr[i];
            }
        }
        return max;
    }
    複製代碼
  • 上界爲其餘類型參數:

    //E是DynamicArray的類型參數,T是addAll的類型參數,T的上界限定爲E
    public <T extends E> void addAll(DynamicArray<T> c){
        for(int i= 0;i<c.length;i++){
            add(c.get(i));
        }
    }
    
    DynamicArray<Number> numbers = new DynamicArray<>();
    DynamicArray<Integer> ints = new DynamicArray<>();
    ints.add(100);
    ints.add(43);
    numbers.addAll(ints);
    複製代碼

解析通配符

  • 通配符: <? extends E>
  • 無限定通配符:, DynamicArray<?> 這種限制:只能讀,不能寫
  • 超類型通配符:<? super E>
  • 通配符比較:
    • 它們的目的都是爲了使方法接口更爲靈活,能夠接受更爲普遍的類型。
    • <? super E> 用於靈活寫入或比較,使得對象能夠寫入父類型的容器,使得父類型的比較方法能夠應用於子類型對象,它不能被類型參數形式替代。
    • <?>和<? extends E> 用於靈活的讀取,使得方法能夠讀取E或E的任意子類型的容器對象,它們能夠用類型參數形式替代,但通配符形式更爲簡潔。

細節和侷限性

  • 使用泛型類、方法和接口 注意點:
    • 基本類型不能用於實例化類型參數
    • 運行時類型信息不適用於泛型
    • 類型擦除可能會引起一些衝突
  • 定義泛型類,方法和接口 注意點:
    • 不能經過類型參數建立對象
    • 泛型類類型參數不能用於靜態變量和方法
    • 瞭解多個類型限定的語法
  • 泛型與數組
    • 不能建立泛型數組
    • Java不支持泛型數組
    • 若是須要存放檢討對象,可使用原始類型的數組,或者使用泛型容器
    • 泛型容器內部使用Object數組,若是要轉換泛型容器爲對應類型的數組,須要使用反射。
相關文章
相關標籤/搜索