Carson帶你學(xué)Java:泛型知識知多少

目錄

  • 定義
  • 意義(即為什么要使用泛型)
  • 作用及特點
  • 原理
  • 額外說明: List<String>能否轉(zhuǎn)為List<Object>?

定義

可理解為 適配廣泛的類型,即參數(shù)化類型,可以把類型像方法的參數(shù)那樣進(jìn)行傳遞。

// 以ArrayList為示例
// 泛型T可以是任意類
public class ArrayList<T> {
    private T[] array;
    //...
}

// 通過泛型的使用,就可創(chuàng)建多種類型的ArrayList
// 1. 可存儲String的ArrayList:
ArrayList<String> strList = new ArrayList<String>();
// 相當(dāng)于
public class ArrayList<String> {
    private String[] array;
    //...
}

// 2. 可存儲Float的ArrayList:
ArrayList<Float> floatList = new ArrayList<Float>();
// 相當(dāng)于
public class ArrayList<Float> {
    private Float[] array;
    //...
}

意義(即為什么要使用泛型)

通過定義一種模板方式結(jié)構(gòu),從而保證類型安全 & 匹配。下面將用ArrayList為示例作為說明。

1. 背景

ArrayList的本質(zhì):一個可變的Object類型數(shù)組

public class ArrayList {
    private Object[] array;
    // ...
}

2. 問題

在使用ArrayList存儲不同類型時,需要強轉(zhuǎn)類型,不然容易出現(xiàn)ClassCastException異常。如存儲String類型:

// 獲取到ArrayList里的Object類型時,必須強制轉(zhuǎn)型為String
// 不然容易出現(xiàn)ClassCastException異常
ArrayList list = new ArrayList();
list.add("carson ho");
String first = (String) list.get(0);

3. 解決方案

使用泛型將ArrayList變成一種模板:ArrayList<T>,就可以創(chuàng)建任意類型的ArrayList。即:

// 泛型T可以是任意類
public class ArrayList<T> {
    private T[] array;
    //...
}

// 多種類型
// 1. 可存儲String的ArrayList:
ArrayList<String> strList = new ArrayList<String>();
// 相當(dāng)于
public class ArrayList<String> {
    private String[] array;
    //...
}

// 2. 可存儲Float的ArrayList:
ArrayList<Float> floatList = new ArrayList<Float>();
// 相當(dāng)于
public class ArrayList<Float> {
    private Float[] array;
    //...
}

作用

  1. 使編譯器可在編譯期間對類型進(jìn)行檢查以提高類型安全,減少運行時由于對象類型不匹配引發(fā)的異常;
  2. 運行時所有的轉(zhuǎn)換都是強制、隱式的,大大提高了代碼的重用率。如對集合類取數(shù)據(jù)時,不需 對存儲的數(shù)據(jù) 進(jìn)行強制類型轉(zhuǎn)換。

原理

基于 類型擦除。即即 使用泛型時加上的類型參數(shù),會在編譯器在編譯時去掉所以,在生成的 Java 字節(jié)碼中,不包含泛型中的類型信息。這里需要特別說明的是:

  • Java中的泛型是在編譯器層次實現(xiàn),編譯器在編譯時盡可能的發(fā)現(xiàn)可能出錯的地方,但仍無法避免在運行時刻出現(xiàn)類型轉(zhuǎn)換異常的情況;
  • 在代碼中定義的List<object> 、List<String>等類型,在編譯后都會變成List
  • JVM看到的只是List,而由泛型附加的類型信息對JVM來說是不可見的

同時需要特別注意的是:

  • 在無泛型的情況下,通常是使用Object類型來進(jìn)行多種類型數(shù)據(jù)的操作,此時操作最多的是針對該Object進(jìn)行數(shù)據(jù)的強制轉(zhuǎn)換
  • 而這種轉(zhuǎn)換是基于開發(fā)者對該數(shù)據(jù)類型明確的情況下進(jìn)行(如將Object型轉(zhuǎn)換為String型);若類型不一致,編譯器在編譯過程中不會報錯,但在運行時會出錯

額外說明: List<String>能否轉(zhuǎn)為List<Object>?

不能。具體描述如下:

示意圖
// 代碼1和代碼2相同
// 代碼1
List<String> strings = new LinkedList<String>( ); 
 List<Integer> ints = new LinkedList<Integer>( );

// 代碼2
 List strings = new LinkedList( ); 
 List ints = new LinkedList( );

// 轉(zhuǎn)換方式可以是如下:
List ss=strings; 
List<Object> objects=ss;

至此,關(guān)于Java中的泛型講解完畢。


歡迎關(guān)注Carson_Ho的簡書!

分享Android技術(shù)干貨,追求短、平、快,但卻不缺深度。


請點贊!因為你的鼓勵是我寫作的最大動力!

相關(guān)文章閱讀
Android開發(fā):最全面、最易懂的Android屏幕適配解決方案
Android事件分發(fā)機制詳解:史上最全面、最易懂
Android開發(fā):史上最全的Android消息推送解決方案
Android開發(fā):最全面、最易懂的Webview詳解
Android開發(fā):JSON簡介及最全面解析方法!
Android四大組件:Service服務(wù)史上最全面解析
Android四大組件:BroadcastReceiver史上最全面解析

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容