繼《? extends T與? super T》以後,咱們再聊聊泛型。html
public interface Generator { <T> T next(); }
第一種解決方法,在方法返回類型前加「<T>」使其成爲一個泛型方法。java
public interface Generator<T> { T next(); }
第二種解決方法,在接口名後加「<T>」使其成爲一個泛型接口。app
泛型類/接口在使用前,必須先指名參數類型,其中除了泛型方法外的泛型參數都將是所指定的類型。以下:ide
// 泛型接口與其子類 public interface Generator<T> { T next(T t); void print(T t); } public class SubGenerator implements Generator<String>{ @Override public String next(String t) { // TODO Auto-generated method stub return null; } @Override public void print(String t) { // TODO Auto-generated method stub } } // 含有泛型方法的接口及其子類 public interface Generator<T> { T next(T t); <U> void print(U t); } public class SubGenerator implements Generator<String>{ @Override public String next(String t) { // TODO Auto-generated method stub return null; } @Override public <U> void print(U t) { // TODO Auto-generated method stub } }
即靜態方法沒法訪問泛型類上定義的泛型,此時採用泛型方法可解決。測試
// 正確作法 public class StaticGenerator { public static <T> T rebey(T t) { return null; } }
在《深刻理解Java虛擬機 JVM高級特性與最佳實踐(高清完整版)》P271 介紹了「當泛型碰見重載」的例子。得出的結論是:url
兩個方法若是有相同的名稱和特徵簽名,但返回值不一樣,那他們也是能夠合法地共存於一個Class文件中的。code
public String url(String s) { return "rebey.cn"; } public int url(String s) { return 0; }
然而以上代碼是沒法編譯經過的。由於此書出版時還未發佈JDK7,所以其實只有JDK1.6及如下才能編譯經過。隨着時間的推移,原來錯的可能因此仍是按咱們原來的理解來解讀重載就行了。同名方法參數個數、順序、類型不一樣,與返回值類型無關。htm
public class Utilities { public static <T> HashSet<T> create(int size) { return new HashSet<T>(size); } public static void print( HashSet<String> h) { for (String s : h) System.out.println(s); } } public class ResultGerneric { public static void main(String[] args) { Utilities.print(Utilities.create(10)); // error in Java 5,6,7 ; fine in Java 8 } }
這是來自GenericsFAQ403中的一個例子。筆者在java7上測試了,如願的看到了錯誤提示:「The method print(HashSet<String>) in the type Utilities is not applicable for the arguments (HashSet<Object>)」。因爲Utilities.create方法未指定具體類型,默認轉爲Object,因此Utilities.print此時沒法接收其做爲String類型的參數。而在Java8版本的增長了類型推斷(type argument inference),可以根據賦值符號左邊值類型自動推斷出右邊。接口
此外,經過顯示指定參數類型也可以解決上述問題:get
public class ResultGerneric { public static void main(String[] args) { Utilities.print(Utilities.<String>create(10));//點操做符與方法名之間 } }
在《Think In Java》4th中泛型章節也提到了類似的例子(P363)。
經過幾個泛型的例子,咱們看到:隨着時間的推移,對的可能錯,錯的亦能對。
這不是頗有趣的一件事嗎?
待續...
更多有意思的內容,歡迎訪問筆者小站: rebey.cn