1. 程式人生 > >Java入門(二)——泛型

Java入門(二)——泛型

如果你寫過前端,可能會經常寫一下關於變數型別的判斷,比如:typeof fn === 'function'之類的程式碼。因為JavaScript作為一門弱型別語言,型別的判斷往往需要開發人員自己去檢查。

Java作為一門強型別語言,它的強就強在型別的約束比較嚴格,大多都是在編譯器(IDEA、eclipse...)裡就做了檢查,也就是說你剛敲完一個字元,如果有型別錯誤,下一秒就能提示你哪錯了。這也避免了執行時的錯誤,讓你的程式碼更加的嚴謹。下面就來了解一下為型別約束做出卓越貢獻的人物——泛型。

Java泛型為何而生

Java泛型(generics)是JDK 1.5中引入的一個新特性,泛型提供了編譯時型別安全檢測機制,該機制允許程式設計師在編譯時檢測到非法的型別。泛型的本質是引數化型別,也就是說操作的資料型別被指定為一個引數。

我知道,上面那些乾巴巴的概念對於初學者看了也是一頭霧水。下面讓我們穿越回到JDK 1.5之前的時代,當初還沒有泛型的存在,我們是怎麼生活的呢?

泛型解決了哪些痛點

ArrayList可以看做“可變長度”的陣列,用起來比陣列方便。實際上,ArrayList內部就是一個Object[]陣列,配合儲存一個當前分配的長度,就可以充當“可變陣列”:

public class ArrayList {
    private Object[] array;
    private int size;
    public void add(Object e) {...}
    public void remove(int index) {...}
    public Object get(int index) {...}
}

如果有上面的ArrayList儲存String型別,會有這麼幾個缺點:

  • 需求強制手動轉型
  • 不方便,易出錯

例如,程式碼必須這麼寫:

ArrayList list = new ArrayList();
list.add("Hello");
// 獲取到Object,必須強制轉型為String:
String first = (String) list.get(0);

很容易出現ClassCastException,因為容易“誤轉型”:

list.add(new Integer(123));
// ERROR: ClassCastException:
String second = (String) list.get(1);

要解決上面的問題,我們可以為String單獨編寫一種ArrayList

public class StringArrayList {
    private String[] array;
    private int size;
    public void add(String e) {...}
    public void remove(int index) {...}
    public String get(int index) {...} // 注意這個特意做了處理
}

這樣一來,存入的必須是String,取出的也一定是String,不需要強制轉型,因為編譯器會強制檢查放入的型別:

StringArrayList list = new StringArrayList();
list.add("Hello");
String first = list.get(0);
// 編譯錯誤: 不允許放入非String型別:
list.add(new Integer(123));

好了,雖然沒有用泛型,但是藉助勞動人民的智慧結晶,我們也能把這個問題解決掉