java 泛型在類,介面和方法上的應用
阿新 • • 發佈:2018-12-31
雖然我在泛型的使用這塊,應用的地方不是很多,但是還是要總結一下的,這一篇文章主要是從使用的角度,對泛型進行介紹。
如果一個類有一個或者多個型別的變數,那麼這個類就是泛型類,這些型別變數是類的型別引數。下邊這個類是一個簡單的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 {}