模板是泛型编程的基础,它涉及以独立于任何特定类型的方式编写代码。
模板是用于创建泛型类或函数的蓝图或公式。库容器(如迭代器和算法)是泛型编程的示例,并且已使用模板概念进行了开发。
每个容器都有一个单独的定义,例如vector,但是我们可以定义许多不同种类的向量,例如vector <int>或vector <string>。
#include <iostream> #include <string> using namespace std; template <typename T> inline T const& Max (T const& a, T const& b) { return a < b ? b:a; } int main () { int i = 39; int j = 20; cout << "Max(i, j): " << Max(i, j) << endl; double f1 = 13.5; double f2 = 20.7; cout << "Max(f1, f2): " << Max(f1, f2) << endl; string s1 = "Hello"; string s2 = "World"; cout << "Max(s1, s2): " << Max(s1, s2) << endl; return 0; }
输出结果
Max(i, j): 39 Max(f1, f2): 20.7 Max(s1, s2): World
另一方面,Java为泛型。
Java泛型方法和泛型类使程序员可以使用单个方法声明来指定一组相关方法,或者使用单个类声明来指定一组相关类型。
泛型还提供了编译时类型安全性,允许程序员在编译时捕获无效类型。
使用Java泛型概念,我们可以编写一个用于对对象数组进行排序的泛型方法,然后使用Integer数组,Double数组,String数组等调用该泛型方法来对数组元素进行排序。
您可以编写一个可以用不同类型的参数调用的泛型方法声明。根据传递给泛型方法的参数类型,编译器会适当地处理每个方法调用。以下是定义泛型方法的规则-
所有泛型方法声明都有一个类型参数部分,该类型参数部分由方括号(<和>)分隔,该方括号在方法的返回类型(下一个示例中的<E>)之前。
每个类型参数部分都包含一个或多个用逗号分隔的类型参数。类型参数,也称为类型变量,是指定泛型类型名称的标识符。
类型参数可用于声明返回类型,并用作传递给泛型方法的参数类型的占位符,这些参数称为实际类型参数。
像其他任何方法一样,声明泛型方法的主体。请注意,类型参数只能表示引用类型,而不能表示原始类型(例如int,double和char)。
public class GenericMethodTest { //泛型方法printArray- public static < E > void printArray( E[] inputArray ) { //显示数组元素 for(E element : inputArray) { System.out.printf("%s ", element); } System.out.println(); } public static void main(String args[]) { //创建整数,双精度和字符数组 Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println("数组integerArray包含:"); printArray(intArray); // pass an Integer array System.out.println("\nArray doubleArray contains:"); printArray(doubleArray); // pass a Double array System.out.println("\nArray characterArray contains:"); printArray(charArray); // pass a Character array } }
输出结果
数组integerArray包含: 1 2 3 4 5 Array doubleArray contains: 1.1 2.2 3.3 4.4 Array characterArray contains: H E L L O
现在让我们看看模板和泛型之间的区别。区别如下:
它使用类型擦除;这样可以确保在编译时进行更严格的类型检查。Java中的泛型提供了编译时的安全性,并消除了类型转换的需要。它直接存在于Java编译器前端,以确保完成这种擦除。
在C ++中,如果使用了模板,则编译器在用给定类型替换其中的泛型参数之后会再次发出模板代码。
在Java中,即使我们必须指定数据类型(在该数据类型中使用任何对象进行函数调用),我们也不必像使用实际数据类型的C ++那样对它进行类型转换,而不必使用包装器类来进行所需的操作。
Java泛型在初始化时使用类型检查,并生成等效于C ++具有“后继类型”和模板元编程的非泛型代码的字节代码,并为每个实例生成新的类。