Java
的泛型語法已經有太多書講了
這裡不再打字貼書
GP一定有用
不然Java和C#不會約好了似的同時開始支持GP
但大家也清楚
GP和Ruby式的動態OO語言屬於不同的意識形態
如果是一人一票
我想大部分的平民程序員更熱衷動態OO語言的平白自然
但如果不准備跳槽到支持JSR
的動態語言
那還是看看GP吧
胡亂總結泛型的四點作用
第一是泛化
可以拿個T代表任意類型
但GP是被C++嚴苛的靜態性逼出來的
落到Java
C#這樣的花語平原裡
所有對象除幾個原始類型外都派生於Object
再加上Java的反射功能
Java的Collection庫沒有范型一樣過得好好的
第二是泛型 + 反射
原本因為Java的泛型拿不到T
class而覺得泛型沒用
最近才剛剛學到通過反射的API來獲取T的Class
後述
第三是收斂
就是增加了類型安全
減少了強制類型轉換的代碼
這點倒是Java Collection歷來的弱項
第四是可以在編譯期搞很多東西
比如MetaProgramming
但除非能完全封閉於框架內部
框架的使用者和擴展者都不用學習這些東西的用法
否則那就是自絕於人民的票房毒藥
C++的MetaProgramming好厲害吧
但對比一下Python拿Meta Programming生造一個Class出來的簡便語法
就明白什麼才是真正的叫好又叫座
所以
作為一個架構設計師
應該使用上述的第
項用法
在框架類裡配合使用反射和泛型
使得框架的能力更強
同時采用收斂特性
本著對人民負責的精神
用泛型使框架更加類型安全
更少強制類型轉換
擦拭法避免了Java的流血分裂
大家經常罵Java GP的擦拭法實現
但我覺得多虧於它的中庸特性
如果你用就是范型
不用就是普通Object
避免了Java陣營又要經歷一場to be or not to be的分裂
最大的例子莫過Java
的Collection 框架
比如有些同學堅持認為自己不會白癡到類型出錯
而且難以忍受每個定義的地方都要帶一個泛型定義List〈Book〉
不用強制類型轉換所省下的代碼還不夠N處定義花的(對了
java裡面還沒有tyepdef
)
因此對范型十分不感冒
這時就要齊齊感謝這個搽拭法讓你依然可以對一個泛型框架保持非泛型的用法了
通過反射獲得 T
class
不知為何書上不怎麼講這個
是差沙告訴我才知道的
最經典的應用見Hibernate wiki的Generic Data Access Objects
代碼如下
abstract public class BaseHibernateEntityDao<T> extends HibernateDaoSupport {
private Class<T> entityClass;
public BaseHibernateEntityDao() {
entityClass =(Class<T>) ((ParameterizedType) getClass()
getGenericSuperclass())
getActualTypeArguments()[
];
}
public T get(Serializable id) {
T o = (T) getHibernateTemplate()
get(entityClass
id);
}
}
精華就是這句了
Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass()
getGenericSuperclass())
getActualTypeArguments()[
];
泛型之後
所有BaseHibernateEntityDao的子類只要定義了泛型
就無需再重載getEnttityClass()
get()函數和find()函數
銷益挺明顯的
所以SpringSide的Dao基類毫不猶豫就泛型了
不過擦拭法的大棒仍在
所以子類的泛型語法可不能亂寫
最正確的用法只有
public class BookDao extends BaseHibernateEntityDao<Book>
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26171.html