# 泛型符號 在類別裡用一個「一般化(Generic)的符號」,表示未來該符號可以是任何參考型別; 常用的符號與字義有: * T : Type * E : Element * K : Key * V : Value * R : Result ## 萬用字元「?」(wildcards) | 語法 | 說明 | |-|-| | `<?>` | 可以為任何型別,沒有上/下限。| | `<? extends T>` | 型別必須是 T 或是 T 的**子類別**。T為上限,沒有下限 | | `<? super T>` | 型別必須是 T 或是 T 的**父類別**。T為下限,沒有上限 | ## 泛型裡的多型 ```graphviz digraph dfd{ node [shape=record]; rankdir=BT; classAA [label="{AA||}"]; classA [label="{A||}"]; classB [label="{B||}"]; classC [label="{C||}"]; classA -> classAA classB -> classA classC -> classA } ``` ## 泛型使用萬用字元(wildcards)注意事項 ||`<?>`|`<? extends T>`|`<? super T>`| |-|-|-|-| |檢視成員|只能用 Object 型別檢視|使用 T 或其父類別檢視成員|只能用 Object 型別檢視| |增加成員|無法增加成員|無法增加成員|可以增加 T 或其子類別的成員| ## 範例 ### `<?>` ```java= private static void process(List<?> list) { // list 可以是任意型別,所以一律無法加入元素,以避免 List<B> 加入 new C() // list.add(new Object()); // compile error! // list.add(new A()); // compile error! // list.add(new B()); // compile error! // list.add(new C()); // compile error! // 可以用 Objcet 參照 for (Object obj : list) System.out.println(obj); } private void testProcess() { process(new ArrayList<AA>()); process(new ArrayList<A>()); process(new ArrayList<B>()); process(new ArrayList<C>()); } ``` ### `<? extends A>` ```java= private void process(List<? extends A> list) { // list 可以是ArrayList<A>, ArrayList<B>或ArrayList<C>型別 // 所以無法加入元素,以避免 List<B> 加入 new C() // list.add(new AA()); // compile error! // list.add(new A()); // compile error! // list.add(new B()); // compile error! // list.add(new C()); // compile error! for (A a : list) System.out.println(a.getClass().getName()); } private void testProcess() { // process(new ArrayList<AA>()); // compile error! process(new ArrayList<A>()); process(new ArrayList<B>()); process(new ArrayList<C>()); } ``` ### `<? super A>` ```java= private void processElements(List<? super A> list) { // list.add(new AA()); // compile error! list.add(new A()); list.add(new B()); list.add(new C()); // list 可以是ArrayList<AA>或ArrayList<A> // 所以僅可以用Object參照 // for (A a : list) System.out.println(a); // compile error! for (Object obj : list) System.out.println(obj); } private void testProcess() { process(new ArrayList<AA>()); process(new ArrayList<A>()); // process(new ArrayList<B>()); // compile error! // process(new ArrayList<C>()); // compile error! } ``` ###### tags: `Java` `泛型` `Generics`