關於C#、java泛型的看法
過去曾經有很長一段時間,直至現在,存在這樣的一種觀點,就是C#比Java的實現更漂亮。《Think in java》的作者Bruce Eckel曾經公開質疑過Java 5提供的泛型。不過說實在,我一直不喜歡看Bruce Eckel的書,感覺上他不是一個有經驗有深度的技術人員。
我也很長一段實現認同這樣的觀點,因為人云亦云!
在C# 2.0支援泛型,而且在虛擬機器級別支援,一開始接觸時,感覺是很震撼的,感覺到泛型從此走入主流應用開發了。和C++相比,沒有C++模板那樣強的功能,完全做不到產生式程式設計的效果,也做不到編譯期計算的效果,但是它簡單實用。
Java 5也開始支援泛型,而且最終正式發行比C# 2.0要早,我之前就使用過Beta版本C#的泛型,也熟悉C++的模板語法,可能是內心的傲慢,或者是懶惰,開始時只是將就著按照傳統的經驗使用Java 5提供的泛型。
對事物的一知半解總是令人困擾的,在閱讀分析JDK原始碼時,總會遇到一些Java 5額外提供的泛型用法,一開始忽略不計,但是看多了總會注意到的。
例如java.util.Collections類中的sort方法和binarySearch方法的介面:
public static <T>void sort(List<T>list, Comparator<? super T>c);
public static <T>int binarySearch(List<? extends Comparable<? super T>>list, T key);
extends和super這兩個關鍵字是C#和C++的泛型中都沒有的,為什麼需要這樣的功能呢?
例如如下情形:
class A { }
class B extends A {}
void addAll(List<A> items) {}
如下程式碼:
List<A> aList = ;
List<B> bList = ;
addAll(aList); //可以
addAll(bList); //編譯不通過
addAll(bList)是無法編譯通過的,這一點在Java、C#、C++中都是如此,怎麼辦呢? 在java中如下處理,修改addAll的介面,改為:
void addAll(List<? extends A>items) {}
這樣,addAll(aList)和addAll(bList)都能夠編譯通過了。
另外super關鍵在演算法中更是好用,如上面介紹的Collections.sort方法。如果你想在C#中實現一個和java.util.Collections.sort一樣的方法,你會發現那是做不到的!
為什麼C#和C++無法提供這樣的功能呢?因為C#和C++都是執行時的泛型支援,bList和aList的型別是不一樣的,List<A>和List<B>的實際型別都是不一樣的,執行時對泛型的支援目前還無法象處理陣列引數那樣具備協變能力。而Java的實現是編譯器的特性,這樣做的缺點就是效能沒有得到提升,但是可以提供更好的語法糖。
想起ajoo以前發表的一個觀點,就是在應用開發中,泛型提供的關鍵是型別安全,效能反而是其次。我對此十分認同,重新審視java的泛型,我們會發現其設計頗具創新,而且向後相容良好!
總結一下我的觀點:
Java的泛型,語法有創新,更好用,向後相容,編寫泛型演算法更方便,但是沒有帶來效能提升。
C#泛型,實現有創新,在虛擬機器級別支援,執行時支援泛型,效能有提升,但是不好編寫泛型演算法,不向後相容。
我也很長一段實現認同這樣的觀點,因為人云亦云!
在C# 2.0支援泛型,而且在虛擬機器級別支援,一開始接觸時,感覺是很震撼的,感覺到泛型從此走入主流應用開發了。和C++相比,沒有C++模板那樣強的功能,完全做不到產生式程式設計的效果,也做不到編譯期計算的效果,但是它簡單實用。
Java 5也開始支援泛型,而且最終正式發行比C# 2.0要早,我之前就使用過Beta版本C#的泛型,也熟悉C++的模板語法,可能是內心的傲慢,或者是懶惰,開始時只是將就著按照傳統的經驗使用Java 5提供的泛型。
對事物的一知半解總是令人困擾的,在閱讀分析JDK原始碼時,總會遇到一些Java 5額外提供的泛型用法,一開始忽略不計,但是看多了總會注意到的。
例如java.util.Collections類中的sort方法和binarySearch方法的介面:
public static <T>void sort(List<T>list, Comparator<? super T>c);
public static <T>int binarySearch(List<? extends Comparable<? super T>>list, T key);
extends和super這兩個關鍵字是C#和C++的泛型中都沒有的,為什麼需要這樣的功能呢?
例如如下情形:
class A { }
class B extends A {}
void addAll(List<A> items) {}
如下程式碼:
List<A> aList = ;
List<B> bList = ;
addAll(aList); //可以
addAll(bList); //編譯不通過
addAll(bList)是無法編譯通過的,這一點在Java、C#、C++中都是如此,怎麼辦呢? 在java中如下處理,修改addAll的介面,改為:
void addAll(List<? extends A>items) {}
這樣,addAll(aList)和addAll(bList)都能夠編譯通過了。
另外super關鍵在演算法中更是好用,如上面介紹的Collections.sort方法。如果你想在C#中實現一個和java.util.Collections.sort一樣的方法,你會發現那是做不到的!
為什麼C#和C++無法提供這樣的功能呢?因為C#和C++都是執行時的泛型支援,bList和aList的型別是不一樣的,List<A>和List<B>的實際型別都是不一樣的,執行時對泛型的支援目前還無法象處理陣列引數那樣具備協變能力。而Java的實現是編譯器的特性,這樣做的缺點就是效能沒有得到提升,但是可以提供更好的語法糖。
想起ajoo以前發表的一個觀點,就是在應用開發中,泛型提供的關鍵是型別安全,效能反而是其次。我對此十分認同,重新審視java的泛型,我們會發現其設計頗具創新,而且向後相容良好!
總結一下我的觀點:
Java的泛型,語法有創新,更好用,向後相容,編寫泛型演算法更方便,但是沒有帶來效能提升。
C#泛型,實現有創新,在虛擬機器級別支援,執行時支援泛型,效能有提升,但是不好編寫泛型演算法,不向後相容。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-448862/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於泛型泛型
- 關於Java和C#的型別對比JavaC#型別
- 【C#】-泛型C#泛型
- C#泛型C#泛型
- C# 泛型C#泛型
- 關於Java中泛型、反射和註解的掃盲篇Java泛型反射
- 【java】【泛型】泛型geneticJava泛型
- C#泛型集合C#泛型
- 淺談C#泛型C#泛型
- C#泛型學習C#泛型
- C#泛型約束C#泛型
- Java中的泛型Java泛型
- Java中基於泛型的交叉型別 - {4Comprehension}Java泛型型別
- Java泛型Java泛型
- C# 泛型集合的自定義型別排序C#泛型型別排序
- c#——泛型的多種應用C#泛型
- 詳解C#泛型(一)C#泛型
- 詳解C#泛型(三)C#泛型
- 詳解C#泛型(二)C#泛型
- Java的泛型機制Java泛型
- Java泛型的那些事Java泛型
- Java中的泛型方法Java泛型
- 我理解的 Java 泛型Java泛型
- Java™ 教程(泛型的限制)Java泛型
- Java-泛型Java泛型
- Java(7)泛型Java泛型
- Java+泛型Java泛型
- Java 泛型原理Java泛型
- java泛型一二Java泛型
- C#泛型鍵值對集合C#泛型
- C#基礎:泛型委託C#泛型
- 理解C#泛型運作原理C#泛型
- c#中判斷類是否繼承於泛型基類C#繼承泛型
- Java泛型裡的Intersection TypeJava泛型
- 深入解析Java中的泛型Java泛型
- java泛型的侷限探究Java泛型
- Java的泛型詳解(一)Java泛型
- Java™ 教程(泛型原始型別)Java泛型型別
- Java基礎 —— 泛型Java泛型