引言
我們使用object和泛型做形參,都是為了讓這個方法能接收更多類型的對象,讓程序變得更健壯,代碼復用率更高。當我們回看自己寫的代碼時會發現,好像使用泛型的地方使用object也可以,使用object的地方使用泛型同樣能實現,那么,本文就說一下,泛型和object的卻別
正題
先上舉例來說明一下object和泛型的使用場景吧,有這樣一個需求:寫一個數字排序的算法,我們知道java中的數字類型有Double、Float、Byte、Short、Integer 以及 Long。
方法一:每種數字類型寫一個方法,需要寫6個方法
class Sort {
void sort(Integer[] sort) {
// 排序
}
void sort(Double[] sort) {
// 排序
}
}
方法二:使用object,只需要寫一個方法。
class Sort { void sort(Object[] sort) { Number[] numbers = (Number[]) sort; // 排序 } }
方法三:使用泛型
class Sort { <T> void sort(T[] sort) { Number[] numbers = (Number[]) sort; // 排序 } }
好了,開始測試
public static void main(String[] args) { Test t=new Test(); t.sort(new Integer[]{2,3}); t.sort1(new Integer[]{2,3}); } <T> void sort(T[] sort) { Number[] numbers = (Number[]) sort; } void sort1(Object[] sort) { Number[] numbers = (Number[]) sort; // 排序 }
編譯沒毛病,運行也不會有毛病,別急我們再寫一個列子
public static void main(String[] args) { Test t=new Test(); t.sort(new String[]{"a","b"}); t.sort1(new String[]{"a","b"}); } <T> void sort(T[] sort) { Number[] numbers = (Number[]) sort; //排序 } void sort1(Object[] sort) { Number[] numbers = (Number[]) sort; // 排序 }
編譯沒毛病,運行一下:
我們最頭疼的就是這種運行時的錯誤了,在大型項目中都需要編譯好后部署然后運行,所以大家都希望問題在編譯期就暴露出來,不要等到運行時才發現問題,那么問題來了有沒有一種寫法能夠讓他在編譯器發現問題呢?看下面這個例子
class Sort { <T extends Number> void sort(T[] sort) { Number[] numbers = (Number[]) sort; // 排序 } }
測試代碼
顯然使用T extends這中寫法能讓問題在編譯期暴露
問題的解決方法有了,總結一下
1、使用object作為形參當需要進行類型強制轉換時,編譯期不會檢查類型是否安全,運行期才會檢查
2、泛型寫法范型的指定保證了代碼的健壯性,避免了強轉的風險.
完畢
結后語
我相信大家在寫這個算法時選形參的類型時,大部分猿都不會選object,而選Number,是的選Number做形參,一切問題都掃除了,但是本文只討論泛型的優點