前言:先說兩個快捷鍵sql
1. Ctrl + Shift + R :查找當前項目中的類編程
2. Ctrl + Shift + T:查找源碼JAR包中的類數組
1、概述編程語言
1.泛型是JDK1.5之後纔有的, 能夠在編譯時期進行類型檢查,且能夠避免頻繁類型轉化!函數
2.泛型擦除:泛型只在編譯時期有效,編譯後的字節碼文件中不存在有泛型信息!下面兩個方法不是方法重寫測試
public void save( List<Person> p ){} public void save( List<Data> d ){}
3.聲明泛型集合,集合兩端類型必須一致;泛型類型必須是引用類型,不能爲基本類型。this
2、泛型方法/泛型類/泛型接口/泛型關鍵字spa
1.做用:設計公用的類、方法,對公用的業務實現進行抽取;使程序更靈活。設計
2.泛型方法:code
public class GenericDemo { // 定義泛型方法,<K,T>表示類型定義 public <K, T> T save(T t, K k) { return null; } // 測試方法 @Test public void testSave() { // 使用泛型方法: 在使用泛型方法的時候,肯定泛型類型 save(1.0f, 1); } }
3.泛型類:
public class GenericDemo<T> { // 定義泛型方法,<K,T>表示類型定義 public <K> T save(T t, K k) { return null; } public void update(T t) { } // 測試方法 @Test public void testSave() { // 泛型類: 在建立泛型類對象的時候,肯定類型 GenericDemo<String> demo = new GenericDemo<String>(); demo.save("test", 1); } }
4.泛型接口
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> {
5.泛型關鍵字
泛型中:
? 指定只是接收值
extends 元素的類型必須繼承自指定的類
super 元素的類型必須是指定類的父類
1)關鍵字:?
public class App_extends_super { // 只帶泛型特徵的方法 public void save(List<?> list) { // 只能獲取、迭代list; 不能編輯list } @Test public void testGeneric() throws Exception { // ? 能夠接收任何泛型集合, 可是不能編輯集合值; 因此通常在方法參數中用 List<?> list = new ArrayList<String>(); // list.add("");// 報錯 } }
2)關鍵字:extends
public class App_extends_super { /** * list集合只能處理 Double/Float/Integer等類型 限定元素範圍:元素的類型要繼承自Number類 (上限) * * @param list */ public void save(List<? extends Number> list) { } @Test public void testGeneric() throws Exception { List<Double> list_1 = new ArrayList<Double>(); List<Float> list_2 = new ArrayList<Float>(); List<Integer> list_3 = new ArrayList<Integer>(); List<String> list_4 = new ArrayList<String>(); // 調用 save(list_1); save(list_2); save(list_3); // save(list_4);//報錯 } }
3)關鍵字:super
public class App_extends_super { /** * super限定元素範圍:必須是String父類 【下限】 * * @param list */ public void save(List<? super String> list) { } @Test public void testGeneric() throws Exception { // 調用上面方法,必須傳入String的父類 List<Object> list1 = new ArrayList<Object>(); List<String> list2 = new ArrayList<String>(); List<Integer> list3 = new ArrayList<Integer>(); save(list1); save(list2); // save(list3);//報錯 } }
3、泛型的反射
設置通用方法,會用到反射泛型!
1.反射泛型涉及的API:
Type:Type 是 Java 編程語言中全部類型的公共高級接口。它們包括原始類型、參數化類型、數組類型、類型變量和基本類型。
例如:
List<String> list = new ArrayList<String>();
泛型集合:list
集合元素定義:new ArrayList<String>()中的String
參數化類型(ParameterizedType):ArrayList<String>爲參數化類型
2.反射泛型案例
public class AdminDao extends BaseDao<Admin> {} public class AccountDao extends BaseDao<Account> {} /** * 全部dao的公用的方法,都在這裏實現 * @author * */ 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); } } }