函數對象:java
package test; import java.util.Collection; import java.util.Comparator; /** * CaseInsensitiveCompare 就是函數對象 * 具體使用是在main方法中的System.out.println(findMax(arr,new CaseInsensitiveCompare())); * @author Administrator * */ public class GenericMemoryCell { public static <AnyType> AnyType findMax(AnyType[] arr, Comparator<? super AnyType> cmp){ int maxIndex = 0; for(int i=1; i<arr.length; i++){ if(cmp.compare(arr[i], arr[maxIndex]) > 0 ){ maxIndex = i; } } return arr[maxIndex]; } public static void main(String[] args) { String[] arr = {"ZEBRA","alligator","crocodile"}; System.out.println(findMax(arr,new CaseInsensitiveCompare())); } } class CaseInsensitiveCompare implements Comparator<String>{ @Override public int compare(String o1, String o2) { // TODO Auto-generated method stub return o1.compareToIgnoreCase(o2); } }
T表明泛型
?是通配符,不能用於聲明階段數組
使用泛型的一個比較大的做用是方便簡單而且避免了數組的類型兼容性致使的問題並且將運行時異常提早到了編譯時異常。
好比,在泛型以前若是要達到泛型的目的,可使用Object和接口兩種形式:
ide
使用Object的一個問題是須要強制類型轉換。寫入的時候先轉換成了object而後讀出的時候仍然是object所以要作強制類型轉換。
使用接口形式:函數
這種方式必需要求傳遞的對象實現相應的接口,3d
數組類型的兼容性:
設Employee IS-A Person,那麼是否是也意味着Employee[] IS-A Person[],換句話說若是一個程序接收Person[]做爲參數,那麼能不能將Emplyee[]
做爲參數傳遞?其實是能夠的,可是還有一種比較複雜的狀況,假設除了Employee外還有Student IS-A Person,此時考慮下面兩條複製語句:
Person[] arr = new Eemployee[5];
arr[0] = new Student(...);
兩句都能編譯,而實際上arr[0]引用了一個Employee,但是Student IS-NOT-A Employee,這樣就產生了混亂。運行時也不報錯由於不存在類型轉換。
好比上例中的接口形式的代碼。code
使用泛型時對象
在第五行,例如類GenericMemoryCell<String>的write方法須要一個String,傳入其餘類型將產生一個編譯錯誤。
也能夠聲明接口是泛型的好比Comparable,在java5以前不是泛型的他的compareTo方法接收一個Objet做爲參數,所以傳遞給他的參數即便不是個
合理的類型也會編譯,只是在運行的時候報ClassCaseException。可是使用泛型的話在編譯器就能提示處錯誤。blog
泛型集合不具備類型兼容性接口
可使用通配符來實現如上要求編譯器
通配符能夠不帶任何限制使用好比<?>至關於<? extends Object> 或者用super來標識超類而非子類
泛型方法:
有下列緣由使用泛型方法: