C++ 模板與 Java泛型


模板是泛型程式設計的基礎,泛型程式設計涉及以獨立於任何特定型別的方式編寫程式碼。

模板是建立泛型類或函式的藍圖或公式。庫容器(如迭代器和演算法)是泛型程式設計的示例,並且是使用模板概念開發的。

每個容器(例如 vector)只有一個定義,但我們可以定義許多不同型別的 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 {
   // generic method printArray
   public static < E > void printArray( E[] inputArray ) {
      // Display array elements
      for(E element : inputArray) {
         System.out.printf("%s ", element);
      }
      System.out.println();
   }
   public static void main(String args[]) {
      // Create arrays of Integer, Double and Character
      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("Array integerArray contains:");
      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
   }
}

輸出

Array integerArray contains:
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++ 具有“後期繫結”和模板超程式設計,併為每個例項生成新的類。

更新於: 2019-07-30

2K+ 閱讀量

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.