1. 程式人生 > >java核心卷軸之泛型程序設計

java核心卷軸之泛型程序設計

== ext generic 原始類型 檢查 equals 綁定 () 應該

  本文根據《Java核心卷軸》第十二章總結而來,更加詳細的內容請查看《Java核心卷軸》

1. 泛型類型只能是引用類型,不可以使用基本數據類型。

2. 類型變量含義

   E : 集合 K : 關鍵字 V : T : 任意類型

3. 泛型類

  3.1 註意事項

    類型變量聲明放在類名的後面

  3.2 示例

package com.BlueStarWei.generic;

public class Pair<T> {
    
    private T first;
    private T second;
    
    public
Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public void setFirst(T first) { this.first = first; } public T getSecond() { return second; } public void setSecond(T second) {
this.second = second; } }

4. 泛型方法

  4.1 註意事項

    類型變量放在修飾符的後面,返回類型的前面

  4.2 示例

package com.BlueStarWei.generic;

public class GenericMethodDemo{
   public static void main(String[] args) {
     String s = getMiddle("Hello","world","Happy");
     System.out.println(s);//World
   }
   
   //T... 表示可以輸入任意個數的參數
public static <T> T getMiddle(T... a){ return a[a.length / 2]; } }

5. 類型變量的限定<T extends BoundingType>

  5.1 T應該是綁定類型的子類型。T和綁定類型可以是類,也可以是接口。

  5.2 一個類型變量可以有多個限定;如: T extends Comparable & Serializable

  5.3 示例

package com.BlueStarWei.generic;

public class BoundingTypeDemo {
   public static void main(String[] args) {
     Integer[] a = new Integer[]{1,2,3,4};
     int max = getMax(a);
     System.out.println(max);
    
   }
   
   public static <T extends Comparable<T>> T getMax(T[] a){
     if(a == null || a.length == 0) return null;
     T max = a[0];
     for (int i = 0; i < a.length; i++) {
      if(max.compareTo(a[i]) < 0){
        max = a[i];
      }
    }
     return max;
   }
   
}

6. 運行時類型檢查只適用於原始類型

  6.1 校驗情況

if(a instanceof Pair<String>) //編譯報錯
if(a instanceof Pair<T>) //編譯報錯
if(a instanceof Pair) //true

  6.2 getClass返回的是原始類型

Pair<String> a = new Pair<String>("Hello", "World");
Pair<Integer> b = new Pair<Integer>(1,2);
if(a.getClass().equals(b.getClass())){
  System.out.println("true");
  //class  com.ebao.gs.pol.nb.test.Pair
  System.out.println(a.getClass());
}else{
  System.out.println("false");
}

7. Java不支持泛型類型的數組

  7.1 示例

Pair<String>[] as = new Pair<String>[10]; //編譯報錯

  7.2 解決方案: 將參數化對象放入ArrayList

List<Pair<String>> list = new ArrayList<Pair<String>>();

8. 通配符的限定

  8.1 子類型限定

    8.1.1 Pair<? Extends Employee>不能調用setFirst方法,但是可以調用getFirst方法

extends Employee  getFirst()
void setFirst(? extends Employee)

   調用setFirst方法時,編譯器只知道需要某個Employee的子類型,但是不知道具體什麽類型。它拒絕傳遞任何特定類型(?不能用來匹配)。調用getFirst方法時,只是將getFirst的返回值賦值給一個Employee的引用,完全合法。

    8.1.2 示例

public static void minMaxBonus(Manager[] manager, Pair<?     
  extends Manager> result) {
if(manager.length == 0 || manager == null) return;     
Manager minManager = manager[0];
Manager maxManager = manager[0];
for (int i = 0; i < manager.length; i++) {
       if(manager[i].getBonus() < minManager.getBonus())   
            minManager = manager[i];
       if(manager[i].getBonus() > maxManager.getBonus()) 
            maxManager = manager[i];
}
result.setFirst(minManager);//編譯報錯
result.setSecond(maxManager);//編譯報錯
Manager m = (Manager)result.getFirst();
System.out.println(m.getBonus());

  8.2 超類型限定

    8.2.1 Pair<? super Manager>可以調用setFirst方法,但是調用getFirst方法會返回Object對象(可以類型強轉)

void setFirst(? super Manager)
? super Manager getFirst()

  編譯器不知道setFirst方法的確切類型,但是可以用任意Manager對象(或子類型)調用它。然而,如果調用getFirst方法,返回的對象類型就得不到保證。只能把它賦值給一個Object(但是可以類型強制轉換)。

    8.2.2 示例

public static void minMaxBonus(Manager[] manager, Pair<? 
  super Manager> result) {
  if(manager.length == 0 || manager == null) return;
  Manager minManager = manager[0];
  Manager maxManager = manager[0];
      for (int i = 0; i < manager.length; i++) {
        if(manager[i].getBonus() < minManager.getBonus()) 
             minManager = manager[i];
        if(manager[i].getBonus() > maxManager.getBonus()) 
             maxManager = manager[i];
    }
  result.setFirst(minManager);
  result.setSecond(maxManager);
  Manager m = (Manager)result.getFirst();
  System.out.println(m.getBonus());
        
}

  8.3 總結

    通常而言:帶有超類型限定的通配符可以向泛型對象中寫入,帶有子類型限定的通配符可以從泛型對象中讀取。

  8.4 附表(Manager類)

package com.ebao.gs.pol.nb.test;

public class Manager {
  private Long id;
  private String name;
  private Double bonus;
  
  
  public Manager(Long id, String name, Double bonus){
    super();
    this.id = id;
    this.name = name;
    this.bonus = bonus;
  }
  
  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Double getBonus() {
    return bonus;
  }
  public void setBonus(Double bonus) {
    this.bonus = bonus;
  } 
  
}

9.泛型的意義

  減少強制類型轉換的使用

更多內容,請關註:http://www.cnblogs.com/BlueStarWei/

java核心卷軸之泛型程序設計