Java泛型
是J2SE1.5中引入的一個新特性,其本質是參數化類型,也就是說所操做的數據類型被指定爲一個參數(type parameter)這種參數類型能夠用在類、接口和方法的建立中,分別稱爲泛型類、泛型接口、泛型方法。數據結構
有關泛型的基礎知識這裏就不說了,咱們直接來看看Java泛型的高階用法。函數
extends
有時候,你會但願泛型類型只能是某一部分類型,其實就是給泛型參數添加一個界限。其定義形式爲:
<T extends BoundingType>
必定要很是注意的是,這裏的extends不是類繼承裏的那個extends!兩個根本沒有任何關聯。
在這裏extends後的BoundingType能夠是類,也能夠是接口,意思是說,T是在BoundingType基礎上建立的,具備BoundingType的功能。.net
public interface Comparable<T> { public boolean compareTo(T i); } //添加上extends Comparable以後,就能夠Comparable裏的函數了 public static <T extends Comparable> T min(T...a){ T smallest = a[0]; for(T item:a){ if (smallest.compareTo(item)){ smallest = item; } } return smallest; }
從這段代碼也能夠看出,類型綁定有兩個做用:
一、對填充的泛型加以限定
二、使用泛型變量T時,可使用BoundingType內部的函數。3d
通配符
Point point; point = new Point(3,3); point = new Point(4.3f,4.3f); point = new Point(4.3d,4.90d); point = new Point(12l,23l);
各類類型的Point實例,均可以賦值給point了。
這裏的?就是無邊界通配符。它是一個未知的符號,能夠是表明任意的類。code
咱們給通配符加上限定: Point<? extends Number> point;
這裏雖然是指派生自Number的任意類型,但你們注意到了沒: new Point<Number>()也是能夠成功賦值的,這說明包括邊界自身。對象
注意:利用<? extends Number>定義的變量,只可取其中的值,不可修改。看下面代碼:blog
Point<? extends Number> point; point=new Point<Integer>(3,33); Number integer_1=point.getX();//編譯成功 point.setX(new Integer(222));//編譯錯誤
明顯在point.setX(new Integer(122))時報編譯錯誤。但point.getX()卻不報錯。
這是爲何呢?
首先,point的類型是由Point<? extends Number>決定的,並不會由於point = new Point<Integer>(3,3)而改變類型。
正由於point的類型爲 Point<? extends Number> point,那也就是說,填充Point的泛型變量T的爲<? extends Number>,這是一個什麼類型?未知類型!!!怎麼可能能用一個未知類型來設置內部值!這徹底是不合理的。
但取值時,正因爲泛型變量T被填充爲<? extends Number>,因此編譯器能肯定的是Number確定是<? extends Number>的父類,因此不報錯。
也就是說,編譯器,只要能肯定通配符類型,就會容許,若是沒法肯定通配符的類型,就會報錯。繼承
若是說 <? extends XXX>指填充爲派生於XXX的任意子類的話,那麼<? super XXX>則表示填充爲任意XXX的父類!接口
class Employee {} class Manager extends Employee {} class CEO extends Manager {} List<? super Manager> list; list = new ArrayList<Employee>(); list.add(new Employee()); //編譯錯誤 list.add(new Manager());//編譯成功 list.add(new CEO());//編譯成功
編譯器沒法肯定<? super Manager>的具體類型,但惟一能夠肯定的是Manager、CEO確定是<? super Manager>的子類,因此確定是能夠add進去的。
但Employee不必定是<? super Manager>的子類,因此不能肯定,不能肯定的,確定是不容許的,因此會報編譯錯誤。get
總結 ? extends 和 ? super 通配符的特徵,咱們能夠得出如下結論:
◆ 若是你想從一個數據類型裏獲取數據,使用 ? extends 通配符(能取不能存)
◆ 若是你想把對象寫入一個數據結構裏,使用 ? super 通配符(能存不能取)
◆ 若是你既想存,又想取,那就別用通配符。
參考:Java泛型