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 phoneNumbers = new HashMap();
public String getPhoneNumber(String name) {
return phoneNumbers.get(name);
}
...
}

这就是Java泛型的全部内容:转换对象的包装器。那是因为Java泛型没有改进。他们使用类型擦除。之所以做出此决定,是因为Java泛型出现的太晚了,以至于他们不想破坏向后兼容性(Map只要需要a,就可以使用a Map)。将此与未使用类型擦除的.Net / C#进行比较,这会导致各种差异(例如,您可以使用原始类型,IEnumerable并且IEnumerable彼此之间没有任何关系)。

在JDK 1.4上可以使用使用Java 5+编译器编译的泛型的类(假定它不使用任何其他需要Java 5+的功能或类)。

这就是Java泛型被称为语法糖的原因。

但是,关于如何执行泛型的决定产生了深远的影响,以至于(一流的)Java Generics FAQ迅速出现,回答了人们对Java Generics的许多问题。

C ++模板具有Java泛型所没有的许多功能:

使用原始类型参数。

例如:

template
class Matrix {
int T[i][i];
...
}

Java不允许在泛型中使用基本类型参数。

使用默认类型参数,这是我在Java中缺少的功能之一,但是有向后兼容性的原因;

Java允许参数的边界。

例如:

public class ObservableList {
...
}

确实需要强调的是,具有不同参数的模板调用实际上是不同的类型。他们甚至不共享静态成员。在Java中并非如此。

除了与泛型的区别之外,出于完整性的考虑,这里是C ++和Java(以及另一个)的基本比较。

我也可以建议使用Java进行思考。作为C ++程序员,对象之类的许多概念已经是天生的,但是存在细微的差异,因此即使您略过部分内容,也应该有介绍性的文本。

学习Java时,您会学到的很多东西都是库(标准库(JDK中附带的库)和非标准库(包括诸如Spring之类的常用东西)。Java语法比C ++语法更冗长,并且不具有许多C ++功能(例如,运算符重载,多重继承,析构函数等),但这也并非严格使其成为C ++的子集。