泛型類或方法容許用戶指定能夠和這些類或方法一塊兒工做的對象類型(相容的對象)
泛型類ArrayList、泛型接口Comparable
從JDK1.5開始,Java容許定義泛型類、泛型接口、泛型方法數組
泛型就是限制對象的數據類型ide
建立一個存儲字符串的線性表(ArrayList)測試
ArrayList<String> list = new ArrayList<>();
如今就只能向該線性表中添加字符串code
list.add("a");
若是試圖向其中添加非字符串類型,就會產生編譯錯誤對象
list.add(new Person("張三",23));
當沒有使用泛型時,編譯經過,運行也經過,便可以添加任何元素,但這樣作在遍歷元素進行相關操做時會產生隱藏的bug。blog
泛型類型必須是引用數據類型,不能使用基本數據類型。接口
ArrayList<int> list = new ArrayList<>();
ArrayList<Integer> list = new ArrayList<>(); list.add(5); //自動裝箱
使用泛型對數據類型進行限制後,無須類型轉換就能夠從一個線性表中獲取一個值,由於編譯器已經知道了這個元素的類型。ci
ArrayList list = new ArrayList(); list.add("Jone"); //自動提高爲Object類型 list.add("Smith"); String s = (String)(list.get(0));//將Object類型轉爲String類型
ArrayList<Double> list = new ArrayList<>(); list.add(5.5); //5.5 is automatically converted to new Double(5.5) list.add(3.0); //3.0 is automatically converted to new Double(3.0) Double doubleObject = list.get(0); //No casting is needing double d = list.get(1); //Automatically converted to double
能夠爲類或者接口定義泛型。當使用容器類來建立對象,或者使用容器類或接口來聲明引用變量時,必須指定具體的類型。rem
public class Stack<E>{ //構造方法 public Stack(){} //建立數組列表,存儲元素的數據類型爲E,需導包alt+shift+O private ArrayList<E> list = new ArrayList<>(); //返回棧中的元素數目 public int getSize(){ return list.size(); } //返回棧頂元素 public E peek(){ return list.get(getSize() - 1); } //返回並移除棧頂元素 public E pop(){ E o = list.get(getSize() - 1); list.remove(getSize() - 1); return o; } //添加一個新元素到棧頂 public void push(E o){ list.add(o); } //若是棧爲空,就返回true public boolean isEmpty(){ return list.isEmpty(); } @Override public String toString(){ return "stack : " + list.toString(); } }
若使用LinkedList模擬堆棧結構,能夠用getLast()、removeLast()、addLast()方法
上面自定義類的構造方法不是public Stack<E>(){},而是public Stack(){}字符串
泛型可能會有多個參數,應將全部參數一塊兒放在尖括號中,並用逗號分隔開,好比<E1,E2,E3>
能夠定義一個類或接口做爲泛型類或者泛型接口的子類型
例如
public final class String extends Object implements Serializable, Comparable<String>, CharSequence
能夠爲靜態方法定義泛型類型
public clas GenericMethodDemo{ public static void main(String[] args){ Integer[] integers = {1,2,3,4,5}; String[] strings = {"London","Paris","New York","Austin"}; GenericMethodDemo.<Integer>print(integers); GenericMethodDemo.<String>print(strings); } public static <E> void print(E[] list){ for(int i = 0;i<list.length;i++){ System.out.print(list[i]+" "); System.out.println(); } }
爲了聲明泛型方法,將泛型類型<E>置於方法聲明中關鍵字static以後
public static <E> void print(E[] list)
爲了調用泛型方法,須要將實際類型放在尖括號內做爲方法名的前綴。例如,
GenericMethodDemo.<Integer>print(integers); GenericMethodDemo.<String>print(strings);
簡單調用
print(integers); print(strings);
能夠將泛型指定爲另一種類型的子類型,這樣的泛型類型稱爲受限的。例以下面所示的代碼用以測試兩個幾何對象是否具備相同的面積。受限的泛型類型將E指定爲GeometricObject的泛型子類型。此時必須傳遞兩個GeomericObject的實例來調用equalArea
public class BoundedTypeDemo{ public static void main(String[] args){ Rectangle rectangle = new Rectangle(2,2); Circle circle = new Circle(2); System.out.println("Same area?" + equalArea(rectangle,circle)); } public static <E extends GeometricObject> boolean equalArea( E object1,E object2){ return object1.getArea()==object2.getArea(); } }
非受限泛型類型<E>等同於<E extends Object>爲了定義一個類爲泛型類型,須要將泛型類型放在類名以後,例如,GenericStack爲了定義一個方法爲泛型類型,要將泛型類型放在方法返回類型以前,例如,void max(E o1,E o2)