泛型&反射



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);

        }

    }

}

 


反射,可以在運行時期動態創建對象;獲取對象的屬性、方法;

 










發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章