泛型的來源
在Java中,泛型借鑒了C++的模版函數,從而引入了泛型。
- C++泛型
int add(int x,int y){ return x + y; } float add(float x.float y){ return x + y; } double add(double x,double y){ return x + y; } // 泛型函數對上面的整數,浮點數的抽象和實現 template<class T> T add(T x,T y){ return x + y; }
- 自定義泛型
public class MyGeneric { public static void main(String[] args) { // 泛型推斷的一般原則,用於返回泛型參數中的交集,且泛型參數必須為引用類型 // 3 自動裝箱 Integer 5 自動裝箱Integer 所以 推斷出Integer Integer result1 = add(3, 5); // 3.5 自動裝箱 Double 5 自動裝箱Integer 所以推斷出共有的父類Number Number result2 = add(3.5, 5); // 3 自動裝箱Integer str1 String 共有的交集,都是Object Object result3 = add(3, "str1"); } /** * 泛型方法的定義: * 用於放置泛型的類型參數的尖括號應出現在方法的其他所有修飾符之后和在方法的返回類型之前,也就是緊鄰返回值之前,下面的 <T> * 按照慣例,類型參數通常用單個大寫字母表示 * 只有引用類型才會被當作方形方法的參數,會自動裝箱的也算 * @param x * @param y * @return */ public static <T> T add(T x,T y) { // 這里編譯器會報錯:The operator + is undefined for the argument type(s) T, T // 因為不是所有的泛型都支持 + 操作,但是由這個方法可以看到java的類型推斷 // T result = x + y; return null; } }
自定義泛型實戰
- 編寫一個泛型方法,自動將Object類型的對象轉換成其他類型。
/** * 編寫一個泛型方法,自動將Object類型的對象轉換成其他類型。 * @param obj * @return */ private static <T> T autoConvert(Object obj) { return (T) obj; } // 測試代碼 public static void main(String[] args) { Object object = "helloWorld"; String helloworld = autoConvert(object); System.out.println("helloworld = " + helloworld); }
- 定義一個方法,可以將任意類型的數組中的所有元素填充為相應類型的某個對象
/** * 定義一個方法,可以將任意類型的數組中的所有元素填充為相應類型的某個對象 * @param t 數組 * @param obj 對象 */ private static <T> void fillArray(T[] t,T obj) { for (int i = 0; i < t.length; i++) { t[i] = obj; } }
- 采用自定義泛型方法的方式打印出任意參數化類型的集合中的所有內容
/** * 采用自定義泛型方法的方式打印出任意參數化類型的集合中的所有內容 * @param t */ private static <T> void printArray(T[] t) { for (int i = 0; i < t.length; i++) { System.out.println("ele[" + i + "] = " + t[i]); } } /** * 采用自定義泛型方法的方式打印出任意參數化類型的集合中的所有內容 * @param t */ private static <T> void printArray(Collection<T> t) { int i = 0; for (T ele : t) { System.out.println("ele[" + (i++) + "] = " + ele); } }
- 定義一個方法,把任意參數類型的集合中的數據安全地復制到相應類型的數組中
/** * 定義一個方法,把任意參數類型的集合中的數據安全地復制到相應類型的數組中,體現了類型推斷的傳播性,T集合 與 T數組 的一致性 * @param source 源集合 * @param dest 目標數組 */ private static <T> void copy(Collection<T> source, T[] dest) { int i = 0; for (T ele : source) { dest[i++] = ele; } }
- 定義一個方法,把任意參數類型的一個數組中的數據安全地復制到相應類型的另一個數組中
/** * 定義一個方法,把任意參數類型的一個數組中的數據安全地復制到相應類型的另一個數組中 * @param source 源數組 * @param dest 目標數組 */ private static <T> void copy(T[] source, T[] dest) { int i = 0; for (T ele : source) { dest[i++] = ele; } }