java基礎筆記-泛型
十 泛型
泛型,可以理解為就是標籤
集合容器類在設計宣告階段,不能明確其具體儲存的型別,
JDK5之前元素型別只能設定成Object
JDK5之後引入泛型,此時在容器上使用
如Collection
這樣等真正使用時再給E賦值(傳入引數)
10.1 集合中使用泛型
不用泛型
ArrayList list = new ArrayList(); list.add(1); list.add(3); list.add(5); list.add("sdf");//全完正確,編譯不會出問題,但是型別不安全,如果list用來存放成績資料,則執行時可能異常 for(Object score:list){ int stuScore = (Integer)score;//必須強轉,因為score是Object型別的 }
使用泛型
泛型是個型別,不能是基本資料型別
ArrayList<Integer> list = new ArrayList<Integer>();//不能是int list.add(1); list.add("dsf");//報錯了,編譯時進行型別檢查,保證了資料安全 //方式一 for(Integer score:list){ int stuScore=score;//這裡就不用強轉了 } //方式二 Iterator<Integer> iter = list.iterator(); while(iter.hasNext()){ sout(iter.next()); }
HashMap
Map<String,Integer> amp = new HashMap<>();//JDK7之後new後面的<>就可以省略了:型別推斷 map.put("sd",1); map.put("sdf",2); Set<Map.Entry<String,Integer>> entry = map.entrySet(); for(Entry en: entry){ en.getkey(); en.getValue();W } //or Iterator<Map.Entry<String,Integer>> iter =entry.iterator(); while(iter.hasNext()){ Map.Entry<String,Integer> e = iter.next(); e.getKey; e.getValue; }
10.2 自定義泛型
10.2.1 泛型類,泛型介面
通常泛型字母的設定
K V 鍵值 T 類 E 方法
public class Order<T>{
String orderName;
int orderId;
T orderT;
public Order(){}
public Order(... , T orderT){
this. ....
this.orderT=orderT;
}
public T getOrderT(){
return orderT;
}
}
//例項化的時候如果沒有指明泛型得型別,則預設為Object型別
Order o = new Order<String>();//剛開始寫不習慣,前面的<>特別容易忘記
Order<String> o =new Order<>();
繼承:
//繼承時指明泛型
public class SubOrder extends Order<String>{
....
}
SubOrder sub = new SubOrder("aa",1,"OrderT");
//繼承時沒有指明
public class SubOrder<E,T> extends Order<T>{
E subOrderE;
...
}
SubOrder<int,String> subOrder = new SubOrder<>();
class Fu<T1,T2>{
}
class Z1 extends Fu{} // 相當於class Z1 extends Fu<Object,Object>
class Z2 extends Fu<String,Integer>{ } //指明瞭具體型別
class Z3<T1,T2> extends Fu<T1,T2>{ }//全部保留
class Z4<T2> extends Fu<Integer,T2>{ }//部分保留
一個類,例項化成了兩種不同泛型的物件,彼此就沒啥關係啦,不能相互賦值 (編譯就過不了)
異常類不可以有泛型
靜態成員方法的裡不可以有泛型。簡單的說就是從第一個p開始到最後一個}結束,就別有泛型的字母
普通成員方法的trycatch裡面,也不行。
T[] arr =new T[10 ]; 不行!
T[] arr = (T[ ]) new Object[10];
10.2.2泛型方法
啥事泛型方法嘞?
不是說泛型裡使用了類的泛型就叫泛型方法,
//這不是泛型方法
int add(E e);
public List<E> copyXxxx(E[] arr){//編譯器會把E[]認為是個某個宣告的型別的陣列
//這才是
<T> T[ ] toArray(T[ ] a);
public <E> List<E> copyXxxx(E[] arr){
}
//方法使用
List<Integer> list = Order.copyXxxx(new Integer(){1,2,3});//傳入的引數決定了E的型別
泛型方法可以使靜態的!!!!
因為泛型引數是在呼叫時確定的,而不需要類的初始化
但是要區分泛型方法的泛型 和 方法裡類的泛型
10.2.3 例子:DAO類
data(base) access object
問題,表很多,各種型別的,每個型別每個資料都寫增刪改查太麻煩了。所以用泛型
做法:讓資料庫中的每個表對應java中的一個類,操作每個表對應操作類的物件,到底對應的那個類呢?? 對應T
public class DAO<T>{
//增
public void add(T t){
...
}
//刪
public boolean remove(int index){...}
//改
public void update(int index,T t){...}
//查
public T getIndex(int index){return null}
pubcli List<T> getFullIndex(int begin,int end){return null}
//泛型方法
public <E> E getValue(){ //舉例:獲取表中一共有多少條記錄:E賦值為整型Long
//又舉例:獲取全部員工工資,E賦值為浮點型
return null;
}
}
//顧客表
public class Customer{
String name;
...
}
public class customerDAO extens DAO<Customer >{
//空的,啥也不寫
}
//學生表
public class Student{
...
}
public class StudentDAO extends DAO<Student>{//每個XxxxDAO只能操作對應的表
}
//測試
public class DAOTest{
@Test
public void test1(){
CustomerDAO dao1 =new CustomerDAO();
dao.add(new Customer());
List<Customer> list = dao.getFullIndex(10,13);
}
@Test
public void test2(){
StudentDAO dao =new STudentDAO();
dao.add(...);
}
}
10.3 泛型 繼承
List<Object> list=null;
List<String> list3=null;
list=list3;//報錯的,泛型不能多型
//G<Fu>和G<Zi>完全是倆不挨邊的型別,沒有父子關係 ,但是他倆有個公共的爹,G<?>詳見下面
10.4 萬用字元的使用
10.4.1 <?>
如果想寫一個通用的List遍歷函式,Int型的,String型的,Person型的
但是<>沒有多型了,
萬用字元:?
List<Object> list1 = null;
List<String> list3 = null;
LIst<?> list= null;
list = list1;//可以了
list = list3;//可以了
public void show(List<?> list){
Iterator<?> iter = list.iterator();
while(iter.hasNext()){
Object o = iter.next();
sout(obj)
}
}
使用萬用字元之後就不能像普通的那種新增add了
除了新增null之外
10.4.2 有限制的萬用字元
//只允許Person及其父類使用 super限制下的泛型,可以add操作本文來自部落格園,作者:熒惑微光,轉載請註明原文連結:https://www.cnblogs.com/yinghuoweiguang/p/15757447.html