4 回答

TA貢獻1895條經驗 獲得超7個贊
它們之間有很大的區別。在C ++中,您不必為泛型類型指定類或接口。這就是為什么您可以創建真正的泛型函數和類,而不必擔心鍵入錯誤。
template <typename T> T sum(T a, T b) { return a + b; }
上面的方法添加了兩個相同類型的對象,并且可以用于具有“ +”運算符的任何類型T。
在Java中,如果要在傳遞的對象上調用方法,則必須指定一種類型,例如:
<T extends Something> T sum(T a, T b) { return a.add ( b ); }
在C ++中,泛型函數/類只能在標頭中定義,因為編譯器會針對不同的類型(與之一起調用)生成不同的函數。因此編譯速度較慢。在Java中,編譯不會帶來很大的損失,但是Java使用一種稱為“擦除”的技術,其中泛型在運行時被擦除,因此在運行時Java實際上正在調用...
Something sum(Something a, Something b) { return a.add ( b ); }
因此,Java中的通用編程并不是真正有用的,它只是語法上的一點幫助新的foreach構造。
編輯:以上關于有用性的觀點是由一個年輕的自我寫成的。Java的泛型當然有助于類型安全。

TA貢獻1876條經驗 獲得超5個贊
Java泛型是大量 C ++模板不同。
基本上,在C ++中,模板基本上是經過修飾的預處理器/宏集(注意:由于某些人似乎無法理解類推,因此我并不是說模板處理是宏)。在Java中,它們基本上是語法糖,可最大程度地減少對象的樣板轉換。這是對C ++模板與Java泛型的相當不錯的介紹。
要詳細說明這一點:使用C ++模板時,基本上是在創建代碼的另一個副本,就像使用#define宏一樣。這使您可以執行一些操作,例如int在模板定義中使用參數來確定數組的大小等。
Java不能那樣工作。在Java中,所有對象都來自java.lang.Object,因此,泛型之前,您需要編寫如下代碼:
public class PhoneNumbers {
private Map phoneNumbers = new HashMap();
public String getPhoneNumber(String name) {
return (String)phoneNumbers.get(name);
}
...
}
因為所有Java集合類型都使用Object作為其基本類型,所以您可以在其中放置任何內容。Java 5推出并添加了泛型,因此您可以執行以下操作:
public class PhoneNumbers {
private Map<String, String> phoneNumbers = new HashMap<String, String>();
public String getPhoneNumber(String name) {
return phoneNumbers.get(name);
}
...
}
這就是Java泛型的全部內容:轉換對象的包裝器。那是因為Java泛型沒有改進。他們使用類型擦除。之所以做出此決定,是因為Java泛型出現的太晚了,以至于他們不想破壞向后兼容性(Map<String, String>只要需要a,就可以使用a Map)。將此與未使用類型擦除的.Net / C#進行比較,這會導致各種差異(例如,您可以使用原始類型,IEnumerable并且IEnumerable<T>彼此之間沒有任何關系)。
在JDK 1.4上可以使用使用Java 5+編譯器編譯的泛型的類(假定它不使用任何其他需要Java 5+的功能或類)。
這就是Java泛型被稱為語法糖的原因。
但是,關于如何執行泛型的決定產生了深遠的影響,以至于(一流的)Java Generics FAQ迅速出現,回答了人們對Java Generics的許多問題。
C ++模板具有Java泛型所沒有的許多功能:
使用原始類型參數。
例如:
template<class T, int i>
class Matrix {
int T[i][i];
...
}
Java不允許在泛型中使用基本類型參數。
使用默認類型參數,這是我在Java中缺少的功能之一,但是有向后兼容性的原因;
Java允許參數的邊界。
例如:
public class ObservableList<T extends List> {
...
}
確實需要強調的是,具有不同參數的模板調用實際上是不同的類型。他們甚至不共享靜態成員。在Java中并非如此。
除了與泛型的區別之外,出于完整性的考慮,這里是C ++和Java(以及另一個)的基本比較。
我也可以建議使用Java進行思考。作為C ++程序員,對象之類的許多概念已經是天生的,但是存在細微的差異,因此即使您略過部分內容,也應該有介紹性的文本。
學習Java時,您會學到的很多東西都是庫(標準庫(JDK中附帶的庫)和非標準庫(包括諸如Spring之類的常用東西)。Java語法比C ++語法更冗長,并且不具有許多C ++功能(例如,運算符重載,多重繼承,析構函數等),但這也并非嚴格使其成為C ++的子集。

TA貢獻1816條經驗 獲得超4個贊
C ++具有模板。Java具有泛型,看上去有點像C ++模板,但是它們非常非常不同。
顧名思義,模板通過為編譯器提供一個(正在等待...)模板來工作,模板可以通過填充模板參數來生成類型安全代碼。
據我所知,泛型的工作方式相反:編譯器使用類型參數來驗證使用它們的代碼是否是類型安全的,但是生成的代碼根本沒有類型。
將C ++模板視為一個非常好的宏系統,將Java泛型視為自動生成類型轉換的工具。

TA貢獻1846條經驗 獲得超7個贊
C ++模板具有Java泛型所沒有的另一個功能是專業化。這使您可以對特定類型使用不同的實現。因此,例如,您可以為int擁有高度優化的版本,而對于其余類型仍然具有通用版本?;蛘?,您可以為指針和非指針類型使用不同的版本。如果要在傳遞指針時對取消引用的對象進行操作,這將很方便。
添加回答
舉報