1. 程式人生 > 其它 >java基礎筆記-泛型

java基礎筆記-泛型

十 泛型

泛型,可以理解為就是標籤

集合容器類在設計宣告階段,不能明確其具體儲存的型別,

JDK5之前元素型別只能設定成Object

JDK5之後引入泛型,此時在容器上使用引數確定容器中儲存的型別

如Collection,List,ArrayList, 其中就是型別引數:即泛型

這樣等真正使用時再給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