允許對個別泛型的類型參數進行約束,包括以下幾種形式(假設 C是泛型的類型參數, 是一般類、泛類,或是泛型的類型參數):T 是一個類。T 是一個值類型。T 具有無參數的公有建構方法。T 實現接口 I 。T 是 C ,或繼承自 C 。
Java 的泛型
Java 泛型的參數只可以代表類,不能代表個別對象。由於 Java 泛型的類型參數之實際類型在編譯時會被消除,所以無法在運行時得知其類型參數的類型。Java 編譯器在編譯泛型時會自動加入類型轉換的編碼,故運行速度不會因為使用泛型而加快。Java 允許對個別泛型的類型參數進行約束,包括以下兩種形式(假設 T 是泛型的類型參數,C 是一般類、泛類,或是泛型的類型參數):T 實現接口 I 。T 是 C ,或繼承自 C 。一個泛型類不能實現Throwable接口。
C++ 的泛型(模板)
C++ 無法對泛型的類型參數進行約束。在編譯時,每個被使用的封閉泛型類型(即是所有泛型參數的實際類型都已被指明的泛型)都會有獨立的編碼產生,編譯器會在此時確保類型安全性。可是如果泛型要運用其泛型參數的某成員,而該泛型參數又不包含該成員的時候,編譯器所產生的錯誤信息會看似與實際問題無關,增加出錯的難度。
注意,T 可用於 Node 嵌套類。如果使用具體類型實例化 GenericList<T>(例如,作為 G
// type parameter T in angle bracketspublicclass public class GenericList<T> { // The nested class is also generic on T private class Node { // T used in non-generic constructor public Node(T t) { next = null; data = t; } private Node next; public Node Next { get { return next; } set { next = value; } } // T as private member data type private T data; // T as return type of property public T Data { get { return data; } set { data = value; } } } private Node head; // constructor public GenericList() { head = null; } // T as method parameter type: public void AddHead(T t) { Node n = new Node(t); n.Next = head; head = n; } public IEnumerator<T> GetEnumerator() { Node current = head; while (current != null) { yield return current.Data; current = current.Next; } }}
class TestGenericList{ static void Main() { // int is the type argument GenericList<int> list = new GenericList<int>(); for (int x = 0; x < 10; x++) { list.AddHead(x); } foreach (int i in list) { System.Console.Write(i + " "); } System.Console.WriteLine("\nDone"); } }