1. 泛型
1.1基本知識:
基本用法、泛型擦除、泛型類/泛型方法/泛型接口、泛型關鍵字、反射泛型(案例)!
作用: 泛型是JDK1.5以後纔有的, 可以在編譯時期進行類型檢查,且可以避免頻繁類型轉化!
1.2 泛型擦除: 泛型只在編譯時期有效,編譯後的字節碼文件中不存在有泛型信息!
/* * 泛型擦除實例
public void save(List<Person> p){ } public void save(List<Dept> d){ // 報錯: 與上面方法編譯後一樣 } */ |
1.3.泛型寫法:
@Test
public void testGeneric3() throws Exception {
// 聲明泛型集合,集合兩端類型必須一致
List<Object> list = new ArrayList<Object>();
List<String> list1 = new ArrayList<String>();
List list2 = new ArrayList<String>();
List<Integer> list3 = new ArrayList();
// 錯誤
//List<Object> list4 = newArrayList<String>();
// 錯誤: 泛型類型必須是引用類型,不能爲基本類型
List<int> list5 = new ArrayList<int>();
}
1.4泛型方法
public class GenericDemo {
// 定義泛型方法
public <K,T>T save(T t,K k) {
return null;
}
// 測試方法
@Test
public void testMethod() throws Exception {
// 使用泛型方法: 在使用泛型方法的時候,確定泛型類型
save(1.0f, 1);
}
}
1.5泛型類:
public class GenericDemo<T> {
// 定義泛型方法
public <K> T save(T t,K k) {
return null;
}
public void update(T t) {
}
// 測試方法
@Test
public void testMethod() throws Exception {
// 泛型類: 在創建愛泛型類對象的時候,確定類型
GenericDemo<String> demo = new GenericDemo<String>();
demo.save("test", 1);
}
}
1.6泛型接口
/**
* 泛型接口
* @author Jie.Yuan
*
* @param <T>
*/
public interface IBaseDao<T> {
void save(T t );
void update(T t );
}
泛型接口類型確定: 實現泛型接口的類也是抽象,那麼類型在具體的實現中確定或創建泛型類的時候確定
public class BaseDao<T> implements IBaseDao<T> {
泛型接口類型確定: 在業務實現類中直接確定接口的類型
public class PersonDao implements IBaseDao<Person>{
1.7 泛型關鍵字:
泛型中:
? 指定只是接收值
extends 元素的類型必須繼承自指定的類 上限
super 元素的類型必須是指定的類的父類 下限
快捷鍵:
Ctrl + shift + R 查看當前項目中類
Ctrl + shift + T 查看源碼jar包中的類
1.8 泛型的反射:
案例,設置通用方法時,會用到反射泛型!
反射泛型涉及API:
Student 類型的表示
Id name
ParameterizedType 參數化類型的表示
ArrayList<String>();
Type 接口,任何類型默認的接口!
包括:引用類型、原始類型、參數化類型
List<String> list = new ArrayList<String>();
泛型集合: list
集合元素定義:new ArrayList<String>(); 中的String
參數化類型: ParameterizedType
即:“ArrayList<String>” 爲參數化類型
public class AdminDao extends BaseDao<Admin> {} public class AccountDao extends BaseDao<Account> {}
|
/** * 所有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); } } }
|
反射,可以在運行時期動態創建對象;獲取對象的屬性、方法;