如何使用泛型(一)

如何使用泛型(一) Generic(泛型)是java 5.0以後的產物, 在還沒有泛型之前,
如果你有兩個類別是長這樣
class A{
    private String s;
    public String getData() {
        return s;
    }
    public void setData(String s) {
        this.s = s;
    }
}
class B{
    private Integer i;
    public Integer getData() {
        return i;
    }
    public void setData(Integer i) {
        this.i = i;
    }
}
乍看之下會發現這兩個類別除了型態不同以外,
其他部分其實都相同,
因此會重構一下。
class Obj{
    private Object o;
    public Object getData() {
        return o;
    }
    public void setData(Object o) {
        this.o = o;
    }
}
這樣看起來清爽多了, 如果要使用的人,
傳入自己需要的型態, 取出則轉型回傳入的型態, 多方便。
Obj o1 = new Obj();
o1.setData("String type");
String s = (String) o1.getData();
System.out.println(s);

Obj o2 = new Obj();
o2.setData(1);
int i = (int) o2.getData();
System.out.println(i);
印出的結果
String type
1
可是這樣就會出現一些問題,
假設傳入的人跟讀取的人是不同人,
他可能會不知道傳入的型態是什麼,
又或者轉型的時候, 給它不對的型態。
Obj o1 = new Obj();
o1.setData("String type");
int s = (int) o1.getData();
System.out.println(s);
結果就會變成
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
如果改用泛型, 則會變成
class Obj<T>{
    private T t;
    public T getData() {
        return t;
    }
    public void setData(T t) {
        this.t = t;
    }
}
改成這樣使用它
Obj<String> o1 = new Obj<>();
o1.setData("String type");
System.out.println(o1.getData());

Obj<Integer> o2 = new Obj<>();
o2.setData(1);
System.out.println(o2.getData());
結果
String type
1
完全不用管型態, 變得比較方便。