# Generic ## introduction 假設我們有: ```java= class IntegerCoordinate { public Integer x; public Integer y; public IntegerCoordinate(Integer x,Integer y) { this.x = x; this.y = y; } } class FloatCoordinate { public Float x; public Float y; public FloatCoordinate(Float x,Float y) { this.x = x; this.y = y; } } ``` 假設我們兩個class的成員幾乎相似,但只有物件Type不同 我們可以寫成 ```java= class Coordinate { public Object x; public Object y; public Coordinate(Object x,Object y) { this.x = x; this.y = y; } } ``` 並且使用: ```java= public class Main { public static void main(String[] args) { Coordinate c = new Coordinate(10,20); Integer i = (Integer) c.x; } } ``` 但假設你記錯了呢? 你放入的是浮點數 ```java= public class Main { public static void main(String[] args) { Coordinate c = new Coordinate(10.5,20.5); Integer i = (Integer) c.x; //出錯 } } ``` ## implementation 所以我們可以把 ```java= class Coordinate { public Object x; public Object y; public Coordinate(Object x,Object y) { this.x = x; this.y = y; } } ``` 內的"Object" 全部改成一個自訂的名稱,通常叫做T (Type) 並且在className後面寫```<T>```來表示T是我們的泛型代號 如果有多個,可以用<T,T2,T3...>表示 Key,Value通常使用<K,V> Element通常使用<E> ```java= class Coordinate<T> { private T x; private T y; public Coordinate(T x,T y) { this.x = x; this.y = y; } public T getX() { return x; } public void setX(T x) { this.x = x; } public T getY() { return y; } public void setY(T y) { this.y = y; } } ``` 使用時,把後面的```T```取代成你要的Type(不能是primitive) ```java= public static void main(String[] args) { Coordinate<Integer> c = new Coordinate<>(10,20); c.setX(30); Integer i = c.getX(); //30 } ``` 如果想要限定某泛型只能是某類別的子類別 可以寫說```T extends AnotherClass``` 像是 ```java= class Test<T extends Anotherclass> { //... } ``` 還有另一種是界定父類別的: ```java= class Test<T super Anotherclass> { //... } ``` Static Method: ```java= public static <T> void aStaticMethod(T t) { System.out.println(t.getClass().getName() +" "+t); } ``` ## Wildcard ```<?>```可以用來表示任意泛型 但是這代表不確定這個泛型的類別 如果對她進行某特定類別操作 會無法編譯 像這裡, 我不知道Coordinate<E>的E是什麼類別,所以我打個``?`` 但是底下又用了Integer ```java= Coordinate<?> c = new Coordinate<>(10,20); c.setX(30); //error Integer i = c.getX(); //error ``` 以下範例就沒問題: ```java= public static void main(String[] args) { Coordinate<?> c = new Coordinate<>(10,20); printCoordinate(c); Coordinate<Double> c2 = new Coordinate<>(30.5,40.5); printCoordinate(c2); } public static <T> void printCoordinate(Coordinate<?> t) { System.out.println(t.getX()+" "+t.getY()); } ```