1、爲何要使用泛型程序設計java
一、泛型程序設計:覺得這編寫代碼能夠被不少不一樣類型的對象所重用。例如:咱們沒必要爲了彙集String和File而別設計不一樣的類;數組
二、使代碼具備更好的可讀性:ArrayList<String> str = new ArrayList<>(); 人們一看就知道是包含了String對象的數組列表;this
2、定義簡單的泛型類spa
泛型類:就是具備一個或多個類型變量的類。設計
聲明語法:public class ClassName<T> {...}code
例: 對象
public class Pair<T> { private T first; private T second; public Pair(){ first = null; second = null; } public Pair(T frist,T second){ this.first = first; this.second = second; } public T getFirst(){ return first; } public T getSecond(){ return second; } public void setFirst(T first){ this.first = first; } public void setSecond(T second){ this.second = second; } }
Pair 類引入了一個類型變量 T ,用 (<>)括起來,並放在類名後邊。泛型變量也能夠有多個類型變量。例如:public class Pair<T,U>{.....}blog
注意:建議類型變量使用大寫字母,並且要比較短。泛型類要寫在一個單獨的文件中。接口
用具體的類型替換類型變量就能夠實例化泛型類型:Pair<String> pair = new Pair(); 或 Pair pair = new Pair(String,String);get
3、泛型方法:
例如:
class ArrayAlg{ public static <T> T getA (T a){ //方法體;
return a; } }
注意:泛型方法既能夠在泛型類中定也能夠在普通類中定義。類型變量放在修飾符的後邊,返回類型的前面。
方法的調用:String a = ArrayAlg.<String>gerA("hello world");在這種狀況下(也是在大多數狀況下)編譯器有足夠的信息可以判斷所調用方法的類型,因此方法調用中能夠省略<String>類型參數。
4、變量類型的限定
有時候咱們要對類型變量加以約束,看下面的例子:
public class ArrayAlg { public static <T> T min(T[] a){ if(a == null || a.length == 0){ return null; } T smallest = a[0]; for(int i = 1;i < a.length;i++){ if(smallest.compareTo(a[i]) > 0) //error The method compareTo(T) is undefined for the type T return smallest = a[i]; } return smallest; } }
代碼中變量smallest 類型爲T ,這意味着它能夠是任意一個類的對象。那麼問題來了,咱們怎麼才能確信T所屬的類有compareTo方法呢??解決這個問題的方法就是將T限制爲實現了Comparable接口的類。能夠經過對類型變量T設置限定實現這一點:
public static <T extends Comparable> T min(T[] a){........}
如今,泛型方法min只能被實現了Comparable接口的類(如String,LocalDate 等)的數組調用。
又一個問題出現了,衆所周知Comparable是一個接口那麼爲何要用關鍵字extends 而不是 implements呢?
記法:<T extends BoundingType > 表示T應該是綁定類型的子類型,T和綁定類型均可以是類,也能夠是接口。選擇關鍵字extends的緣由是更接近於子類的概念。並且java設計者也不打算在語言中再添加一個新關鍵字了。
一個類型變量能夠有多個限定,限定類型用「&」 分割,而逗號用來分割類型變量。例如:<T extends Comparable & Serializable,U extends String>
注意:能夠根據需求有多個接口做爲限定類,可是限定中至多有一個類。