1.泛型的概念
泛型的作用, 泛型語法(泛型方法,泛型類,泛型接口),泛型關鍵字(extends/super),反射泛型
4.1 泛型的作用
泛型
1)可以減少手動類型轉換的工作
2)可以把程序運行時錯誤提前到編譯時報錯!!
好處: 使用泛型可以讓開發者寫出更加通用的代碼!!!!!!!
2.jdk1.4和jdk1.5的變化
public void test(){
/**
* jdk1.4或以前的做法
*/
List list = new ArrayList();
//存儲
list.add(new Cat());
list.add(new Dog());
//取出
Cat cat = (Cat)list.get(0);
//運行的時候報錯,類型轉換錯誤
//Cat cat2 = (Cat)list.get(1);
/**
* jdk1.5 之后
* 泛型的作用1: 把運行的可能經常導致的類型轉換錯誤,提前到編譯時檢測類型。
* 泛型的作用2: 減少手動類型轉換的工作
*/
List<Cat> list2 = new ArrayList<Cat>();
list2.add(new Cat());
//編譯的時候報錯,類型無法存入List集合
//list2.add(new Dog());
List<String> list3 = new ArrayList<String>();
list3.add("eric");
list3.add("jacky");
list3.add("rose");
/**
* jdk1.4或以前的做法
*/
//遍歷
for (Object obj : list3) {
//如果這時需要調用String特有的方法
String str = (String)obj;
System.out.println(obj);
}
/**
* jdk1.5之后的做法
*/
for (String obj : list3) {
System.out.println(obj);
}
}
3.泛型語法
3.1泛型方法
/**
* 設計一個通用的方法,可以接收任何類型
* 泛型方法的作用是可以讓開發者設計出更加通過的方法
* @param dept
*/
public <T,K> T save(T t,K k){
return t;
}
注意: 泛型方法在調用方法時確定類型
3.2泛型類
/**
* 泛型方法和泛型類
* @author APPle
*
*/
public class Demo2<T,K> {
/**
* 設計一個通用的方法,可以接收任何類型
* 泛型方法的作用是可以讓開發者設計出更加通過的方法
* @param dept
*/
public T save(T t,K k){
return t;
}
public void update(T t,K k){
}
注意:泛型類的定義了泛型,那么方法上如果使用的同一個類型,那么方法就不需要定義泛型
泛型類的類型是在創建類的對象時確定!!
3.3泛型接口
/**
* 泛型接口
* 泛型接口的類型確定:
* 1)直接實現泛型接口的時候可以確定類型
* 2)繼承泛型接口的實現類的時候可以確定類型
* @author APPle
*/
public class Demo3 {
}
class Employee{}
/*通用的dao接口*/
interface IBaseDao<T>{
public void save(T t);
public void update(T t);
}
/**
* 具體的業務dao
* @author APPle
*
*/
/*class EmpDao implements IBaseDao<Employee>{
@Override
public void save(Employee t) {
}
@Override
public void update(Employee t) {
}
}*/
/**
* 通用的dao實現類
*/
class BaseDao<T> implements IBaseDao<T>{
@Override
public void save(T t) {
//寫通用的增加方法
}
@Override
public void update(T t) {
//通用的修改方法
}
}
/**
* 具體的業務dao實現類
* @author APPle
*
*/
class EmpDao extends BaseDao<Employee>{
}
3.4 泛型關鍵字
?
用于限定泛型的使用范圍!!!!
?
/**
* 沒有加上泛型,則會報警告,希望保持泛型特征
* 注意:
* 如果一個泛型類加上?號泛型,則該類不能再進行編譯,只能用于接收數據
*/
List<?> list = getList();
extend
/**
* 該方法只能接收存放者Number類型的子類對象的List集合
* extends : 只能傳入指定類對象或者指定類的子類
* @param list
*/
public void add(List<? extends Number> list){
}
super
/**
* 該方法只能接收存放者Number類型的父類對象的List集合
* super: 只能傳入指定類的對象或者指定類的父類
* @param list
*/
public void add2(List<? super Number> list){
}
4.反射泛型
/**
* 需要解決的問題:
* 約定: 具體泛型類型的類名 和 表名 保持一致!!!!
* 1) 得到具體的業務dao運行過程中的泛型具體類型(Student/Teacher),可以封裝ResultSet
* 2) 得到泛型具有類型名稱 ,就是表名
*/
//1)this : 代表當前運行的dao對象
//System.out.println(this.getClass());
//2)this.getClass(): 代表當前運行dao對象的Class對象
Class clazz = this.getClass(); //public class TeacherDao extends BaseDao<Teacher>
//3)clazz.getGenericSuperclass(): 得到當前dao對象的父類(參數化類型)
Type type = clazz.getGenericSuperclass(); // BaseDao<Teacher>
//4)把父類的類型強轉成子類(參數化類型: ParameterizedType)
ParameterizedType param = ( ParameterizedType)type; // BaseDao<Teacher>
//5)param.getActualTypeArguments():得到參數化類型 上面的泛型類型列表
Type[] types = param.getActualTypeArguments(); // <Teacher>
//6)取出泛型類型列表中的第一個泛型類型
Type target = types[0]; // Teacher
//7)強制成Class類型
targetClass = (Class)target;