一、什麼是泛型?
Java泛型設計原則:只要在編譯時期沒有出現警告,那麼執行時期就不會出現ClassCastException異常.
泛型:把型別明確的工作推遲到建立物件或呼叫方法的時候才去明確的特殊的型別
引數化型別:
ArrayList<E>中的E稱為型別引數變數
ArrayList<Integer>中的Integer稱為實際型別引數
整個稱為ArrayList<E>泛型型別
整個ArrayList<Integer>稱為引數化的型別ParameterizedType
二、為什麼需要泛型
有了泛型以後:
- 程式碼更加簡潔【不用強制轉換】
- 程式更加健壯【只要編譯時期沒有警告,那麼執行時期就不會出現ClassCastException異常】
- 可讀性和穩定性【在編寫集合的時候,就限定了型別】
在建立集合的時候,我們明確了集合的型別了,所以我們可以使用增強for來遍歷集合!
//建立集合物件
ArrayList<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
//遍歷,由於明確了型別.我們可以增強for
for (String s : list) {
System.out.println(s);
}
三、泛型基礎
泛型類就是把泛型定義在類上,使用者使用該類的時候,才把型別明確下來….這樣的話,使用者明確了什麼型別,該類就代表著什麼型別…使用者在使用的時候就不用擔心強轉的問題,執行時轉換異常的問題了。
在類上定義的泛型,在類的方法中也可以使用!
/*
1:把泛型定義在類上
2:型別變數定義在類上,方法中也可以使用
*/
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
使用者想要使用哪種型別,就在建立的時候指定型別。使用的時候,該類就會自動轉換成使用者想要使用的型別了。
public static void main(String[] args) {
//建立物件並指定元素型別
ObjectTool<String> tool = new ObjectTool<>();
tool.setObj(new String("鍾福成"));
String s = tool.getObj();
System.out.println(s);
//建立物件並指定元素型別
ObjectTool<Integer> objectTool = new ObjectTool<>();
/**
* 如果我在這個物件裡傳入的是String型別的,它在編譯時期就通過不了了.
*/
objectTool.setObj(10);
int i = objectTool.getObj();
System.out.println(i);
}
定義泛型方法….泛型是先定義後使用的
//定義泛型方法..
public <T> void show(T t) {
System.out.println(t);
}
使用者傳遞進來的是什麼型別,返回值就是什麼型別了
public static void main(String[] args) {
//建立物件
ObjectTool tool = new ObjectTool();
//呼叫方法,傳入的引數是什麼型別,返回值就是什麼型別
tool.show("hello");
tool.show(12);
tool.show(12.5);
}
子類明確泛型類的型別引數變數
/*
把泛型定義在介面上
*/
public interface Inter<T> {
public abstract void show(T t);
}
實現泛型介面的類…..
/**
* 子類明確泛型類的型別引數變數:
*/
public class InterImpl implements Inter<String> {
@Override
public void show(String s) {
System.out.println(s);
}
}
四、泛型的應用
當我們寫網頁的時候,常常會有多個DAO,我們要寫每次都要寫好幾個DAO,這樣會有點麻煩。
public abstract class BaseDao<T> {
//模擬hibernate....
private Session session;
private Class clazz;
//哪個子類調的這個方法,得到的class就是子類處理的型別(非常重要)
public BaseDao(){
Class clazz = this.getClass(); //拿到的是子類
ParameterizedType pt = (ParameterizedType) clazz.getGenericSuperclass(); //BaseDao<Category>
clazz = (Class) pt.getActualTypeArguments()[0];
System.out.println(clazz);
}
public void add(T t){
session.save(t);
}
public T find(String id){
return (T) session.get(clazz, id);
}
public void update(T t){
session.update(t);
}
public void delete(String id){
T t = (T) session.get(clazz, id);
session.delete(t);
}
}
繼承抽象DAO,該實現類就有對應的增刪改查的方法了。
public class CategoryDao extends BaseDao<Category> {
}
BookDao
public class BookDao extends BaseDao<Book> {
}