泛型接口類型確定: 實現泛型接口的類也是抽象,那么類型在具體的實現中確定或創建泛型類的時候確定。
泛型的反射
/**
* 所有dao的公用的方法,都在這里實現
* @author Jie.Yuan
*
*/
public class BaseDao<T>{
// 保存當前運行類的參數化類型中的實際的類型
private Class clazz;
// 表名
private String tableName;
// 構造函數: 1. 獲取當前運行類的參數化類型; 2. 獲取參數化類型中實際類型的定義(class)
public BaseDao(){
// this 表示當前運行類 (AccountDao/AdminDao)
// this.getClass() 當前運行類的字節碼(AccountDao.class/AdminDao.class)
// this.getClass().getGenericSuperclass(); 當前運行類的父類,即為BaseDao<Account>
// 其實就是“參數化類型”, ParameterizedType
Type type = this.getClass().getGenericSuperclass();
// 強制轉換為“參數化類型” 【BaseDao<Account>】
ParameterizedType pt = (ParameterizedType) type;
// 獲取參數化類型中,實際類型的定義 【new Type[]{Account.class}】
Type types[] = pt.getActualTypeArguments();
// 獲取數據的第一個元素:Accout.class
clazz = (Class) types[0];
// 表名 (與類名一樣,只要獲取類名就可以)
tableName = clazz.getSimpleName();
}
/**
* 主鍵查詢
* @param id 主鍵值
* @return 返回封裝后的對象
*/
public T findById(int id){
/*
* 1. 知道封裝的對象的類型
* 2. 表名【表名與對象名稱一樣, 且主鍵都為id】
*
* 即,
* ---》得到當前運行類繼承的父類 BaseDao<Account>
* ----》 得到Account.class
*/
String sql = "select * from " + tableName + " where id=? ";
try {
return JdbcUtils.getQuerrRunner().query(sql, new BeanHandler<T>(clazz), id);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 查詢全部
* @return
*/
public List<T> getAll(){
String sql = "select * from " + tableName ;
try {
return JdbcUtils.getQuerrRunner().query(sql, new BeanListHandler<T>(clazz));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}