4.泛型

weixin_34208283發表於2017-08-08
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;

相關文章