1. 程式人生 > >java 泛型在類,介面和方法上的應用

java 泛型在類,介面和方法上的應用

雖然我在泛型的使用這塊,應用的地方不是很多,但是還是要總結一下的,這一篇文章主要是從使用的角度,對泛型進行介紹。

如果一個類有一個或者多個型別的變數,那麼這個類就是泛型類,這些型別變數是類的型別引數。下邊這個類是一個簡單的java類,有一個屬性t,它的型別是Object

方法上的泛型

class DemoClass {
   private Object t;
 
   public void set(Object t) { this.t = t; }
    
   public Object get() { return t; }
}

這裡它可以存入任何型別的資料,沒有任何限制,如果要對它的型別進行限制怎麼辦呢?我們可以進行如下的使用
class DemoClass<T> {
   //T stands for "Type"
   private T t;
 
   public void set(T t) { this.t = t; }
    
   public T get() { return t; }
}

那麼呼叫的時候就會有下邊的結果:
DemoClass<String> instance = new DemoClass<String>();
instance.set("lokesh"); //正確的用法
instance.set(1);        //編譯錯誤

介面上的泛型

我們看下邊這個例子就能快速的理解
// 泛型介面的定義
interface DemoInterface<T1, T2>
{
   T2 doSomeOperation(T1 t);
   T1 doReverseOperation(T2 t);
}
 
//實現泛型介面的類
class DemoClass implements DemoInterface<String, Integer>
{
   public Integer doSomeOperation(String t)
   {
      //其他程式碼
   }
   public String doReverseOperation(Integer t)
   {
      //其他程式碼
   }
}

方法上的泛型

方法上的泛型和類上的泛型很像,唯一不同的是型別的作用域不同。下邊這段使用泛型方法的程式碼用來找出型別相同引數的個數
public static <T> int countAllOccurrences(T[] list, T item) {
   int count = 0;
   if (item == null) {
      for ( T listItem : list )
         if (listItem == null)
            count++;
   }
   else {
      for ( T listItem : list )
         if (item.equals(listItem))
            count++;
   }
   return count;
}  

如果你是傳遞的String的列表,和另一個String,可以正常執行,但是如果你在這個String List中找Number則會出現變異錯誤。

構造方法上的泛型

class Dimension<T>
{
   private T length;
   private T width;
   private T height;
 
   //泛型構造方法
   public Dimension(T length, T width, T height)
   {
      super();
      this.length = length;
      this.width = width;
      this.height = height;
   }
}

使用萬用字元的泛型

通配使用“?”作為標記,代表未知的型別
Collection<?> coll = new ArrayList<String>();
//可以通配所有的型別
List<? extends Number> list = new ArrayList<Long>();
//通配Number子類的型別
Pair<String,?> pair = new Pair<String,Integer>();
//String和其它型別

下邊的程式碼會出錯
List<? extends Number> list = new ArrayList<String>();  
//String 不是Number的子類,所以會出錯
Comparator<? super String> cmp = new RuleBasedCollator(new Integer(100)); 
//String 不是Integer的超類

不允許使用泛型的地方

a) 不能是靜態的型別
public class GenericsExample<T>
{
   private static T member; //This is not allowed
}

b)不能建立T的例項
public class GenericsExample<T>
{
   public GenericsExample(){
      new T();
   }
}

c)在宣告時不能和原生型別一起使用 
final List<int> ids = new ArrayList<>();    //不允許
final List<Integer> ids = new ArrayList<>(); //允許

d) 不能建立泛型的異常類
// 引起編譯錯誤
public class GenericException<T> extends Exception {}