java泛型學(xué)習(xí)

原生態(tài)類型

在沒有泛型之前,如果我們要維護(hù)一個(gè)價(jià)格列表:

public class Main {

    public static void main(String[] args) throws Exception {
        List prices = new ArrayList();
        Integer a = 100;
        prices.add(a);

        System.out.println(prices);
    }
}
/*output:
[100]
 */

當(dāng)有人插入非法數(shù)據(jù)時(shí),編譯也不會報(bào)異常

public class Main {

    public static void main(String[] args) throws Exception {
        List prices = new ArrayList();
        Integer a = 100;
        prices.add(a);

        String b = "test";
        prices.add(b);

        System.out.println(prices);
    }
}
/*output:
[100, test]
 */

但是執(zhí)行的時(shí)候,很容易出現(xiàn)bug:

public class Main {

    public static void main(String[] args) throws Exception {
        List prices = new ArrayList();
        Integer a = 100;
        prices.add(a);

        String b = "test";
        prices.add(b);

        for (Object price : prices) {
            Integer tmp = (Integer)price;
            System.out.println(tmp / 100);
        }
    }
}
/*output:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at com.dpriest.tool.automan.Main.main(Main.java:17)
1
 */

原生態(tài)類型的缺點(diǎn)

  1. 在編譯時(shí)期就無法發(fā)現(xiàn)異常;
  2. 需要手動做類型的轉(zhuǎn)換;

使用泛型

public class Main {

    public static void main(String[] args) throws Exception {
        List<Integer> prices = new ArrayList<Integer>();
        Integer a = 100;
        prices.add(a);

//        String b = "test";//編譯報(bào)錯(cuò),無法通過
//        prices.add(b);

        for (Integer price : prices) {
            System.out.println(price / 100);
        }
    }
}
/*output:
1
 */

什么是泛型

泛型是在Java 1.5發(fā)行版本中增加的。

聲明中具有一個(gè)或者多個(gè)類型參數(shù)的類或者接口,就是泛型類或者接口。

public interface List<E> extends Collection<E>

public interface Map<K,V>

List接口就只有單個(gè)類型參數(shù)E,表示列表的元素類型。

泛型類和接口統(tǒng)稱為泛型。

習(xí)題

  1. 泛型的類型參數(shù)可以為基本類型嗎?
  2. 參數(shù)類型的字母有限制嗎?
  3. 必須用大寫聲明嗎?
  4. 可以用多個(gè)字母聲明嗎?
字母 對應(yīng)的英文單詞 含義
E Element 常用在java Collection里,如:List<E>,Iterator<E>,Set<E>
K,V Key,Value 代表Map的鍵值對
N Number 數(shù)字
T Type 類型,如String,Integer等等

聲明泛型

泛型類

public class CacheData<T> {
    private T data;
    private boolean markedValue;

    public CacheData() {
    }

    public CacheData(T data, boolean markedValue) {
        this.data = data;
        this.markedValue = markedValue;
    }

    public T getData() {
        return data;
    }

    public boolean isMarkedValue() {
        return markedValue;
    }
}

泛型方法

public class TransferService {

    public <T> T transfer(T toTransfer)
    {
    }
}

多個(gè)類型參數(shù)的申明

public interface ITransfer<F, T> {

    T transfer(F from);
}

基于泛型接口的實(shí)現(xiàn)

public class TransferImpl
                implements ITransfer<AService,  BService> {

    @Override
    public BService transfer(AService a) {
    }

}

泛型方法的小技巧

當(dāng)沒有使用泛型方法時(shí),實(shí)例化對象:

List<Integer> prices = new ArrayList<Integer>();
List<String> strings = new ArrayList<String>();

使用泛型方法

public class Main {

    public static void main(String[] args) throws Exception {
        List<Integer> prices = newArrayList();
        Integer a = 100;
        prices.add(a);

        List<String> strings = newArrayList();
        strings.add("String");
    }

    public static <E> List<E> newArrayList() {
        return new ArrayList<E>();
    }
}

泛型方法的特點(diǎn):無需明確指定類型參數(shù)的值,不像調(diào)用泛型構(gòu)造器的時(shí)候是必須指定的。
泛型只在編譯時(shí)強(qiáng)化它們的類型信息,并在運(yùn)行時(shí)擦除它們的元素類型信息。擦除就是使泛型可以與沒有使用泛型的代碼隨意進(jìn)行交互。

無限制通配符類型

無限制通配符類型:List<?>

public class Main {

    public static void main(String[] args) throws Exception {
        List<Integer> prices = new ArrayList<Integer>();
        Integer a = 100;
        prices.add(a);

        List<String> strings = new ArrayList<String>();
        strings.add("String");

        printAnyList(prices);
        printAnyList(strings);
    }

    private static void printAnyList(List<?> list) {
        for (Object o : list) {
            System.out.println(o);
        }
    }
}
/*output:
100
String
 */

習(xí)題

下面兩種使用方式,哪個(gè)更優(yōu)雅?

if (value instanceof List) {}
if (value instanceof List<?>) {}

更高級通配符特性

術(shù)語 實(shí)例
有限制類型參數(shù) <T extends Number>
遞歸類型限制 <T extends Comparable<T>>
有限制通配符類型 List<? extends Number>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • object 變量可指向任何類的實(shí)例,這讓你能夠創(chuàng)建可對任何數(shù)據(jù)類型進(jìn)程處理的類。然而,這種方法存在幾個(gè)嚴(yán)重的問題...
    CarlDonitz閱讀 937評論 0 5
  • 所謂泛型,就是變量類型的參數(shù)化。泛型是java1.5中引入的一個(gè)重要特征,通過引入泛型,可以使編譯時(shí)類型安全,運(yùn)行...
    cvmars閱讀 219評論 0 2
  • 開發(fā)人員在使用泛型的時(shí)候,很容易根據(jù)自己的直覺而犯一些錯(cuò)誤。比如一個(gè)方法如果接收List作為形式參數(shù),那么如果嘗試...
    時(shí)待吾閱讀 1,073評論 0 3
  • 在之前的文章中分析過了多態(tài),可以知道多態(tài)本身是一種泛化機(jī)制,它通過基類或者接口來設(shè)計(jì),使程序擁有一定的靈活性,但是...
    _小二_閱讀 706評論 0 0
  • 扣除的服裝費(fèi) 朋友晴子和蓮子高中到廣州一家粵菜館打暑假工,晴子漂亮,蓮子活潑聰明;2個(gè)人又肯干,很快老板就說要給她...
    小貓_003e閱讀 289評論 0 1