2022-10-19
泛型 類型 問題
泛型的橫空出世
1. 為什么引入泛型/引入泛型的必要性
來,我們深入分析下上述代碼運行時出現錯誤的主要原因:
ArrayList的本質是一個Object數組Object[] elementArr,這種設計雖然體現出來了泛型的思想(泛型:泛指任意類型),但是有以下問題:
ArrayList實例化之后,可以隨意添加任意類型的對象(Obeject是任意引用類型的基類)。
獲取元素的前提是:需要提前知道列表元素的類型。
獲取列表元素時然后進行操作,都需要進行顯式類型轉換,容易發生類型轉換出錯的問題。
由于早期我們開發者經常操作集合對象,所以頻繁的出現運行期間異常問題,這種問題困擾了很多人,SUN官方的設計師們也下定決心解決這個問題,這些大佬們在想: 如果集合能和數組一樣,在定義時就指定好類型,這樣就不會出現運行期間異常問題了,也就規避了很多安全隱患。
所以SUN官方提出了泛型技術來解決操作集合中存在的這些問題。
2. 泛型的引入時機
SUN官方在推出jdk1.5版本時,就對這樣的問題提出了解決方案: 泛型。
泛型的由來:通過Object轉型問題引入 ,早期的Object類型可以接收任意的對象類型,泛型其實指的就是任意的對象類型,但是在實際的使用中,會有類型轉換的問題。也就存在這隱患,所以Java提供了泛型來解決這個安全問題。
所以后期SUN官方的這些大佬們,對泛型的設計核心思想就兩條:
在定義時,泛型可以指任意的對象類型。
在使用時,必須明確泛型的具體對象類型。
來我們看一下,SUN官方jdk1.5之后,對List集合的改造:
/**
* @param <E> the type of elements in this list: 定義List時,E可以指代任意對象的類型
*/
public interface List<E> extends Collection<E> {
----------
}
下面我們看一下List的使用:
public class GenericsDemo {
public static void main(String[] args) {
//1.創建一個List對象:指定泛型為String
List<String> list = new ArrayList<String>();
//2.向List中添加數據:必須添加String類型的數據
list.add("corn");
list.add("java");
//3.遍歷集合
for (int i = 0; i <list.size() ; i++) {
//4.把集合中的每個元素轉成String類型
String ele = (String) list.get(i);
//5.打印-測試結果
System.out.println("元素的值:"+ele);
}
}
}
那么如果我們使用 Listlist 添加其它類型的數據呢?
可以看到下圖:不允許添加除String類型以外的,其它類型的數據,這樣后期操作就不會有問題了。
小伙伴,我們來簡單的總結一下:
雖然泛型在定義時可以表示任意對象的類型,但是我們在使用是,必須明確泛型指代的具體類型,那么就這么一點小小的改動帶來的確實本質性的變化: 一勞永逸,體現了泛型的通用性,規避了很多安全問題。
3. 泛型能做的哪些事
經過我們剛才的"一頓分析與操作",小伙伴應該基本清楚了泛型能夠解決那些問題了。
jdk1.5之后加入泛型,主要是為了解決類型轉換的安全隱患,具體體現如下:
解決泛型對象實例化之后,可以隨意添加任何類型的對象的問題。
解決獲取泛型元素前,需要提前確定元素的類型的問題。
解決獲取元素時,需要進行顯式類型轉換的問題。
解決容易出現類型轉換出錯的問題。
那么小伙伴們,我們通過下面代碼來細細品味一番:
public class GenericsDemo2 {
public static void main(String[] args) {
//1.創建一個泛型為String的集合: 解決泛型對象實例化之后,可以隨意添加任何類型的對象的問題。
List<String> list = new ArrayList<String>();
//2.向List中添加String類型的數據:解決獲取泛型元素前,需要提前確定元素的類型的問題。。
list.add("corn");
list.add("java");
//list.add(66);//報編譯錯誤:不能添加int型的數據
//3.遍歷集合
for (int i = 0; i <list.size() ; i++) {
//4.把集合中的每個元素:解決獲取元素時,需要進行顯式類型轉換的問題。
String ele = list.get(i);// 不需要類型強轉:解決容易出現類型轉換出錯的問題。
//5.打印-測試結果
System.out.println("元素的值:"+ele);
}
}
}
其實看完這些代碼后,想必小伙伴心中都有了一個明確的答案:
之前我們沒有使用泛型操作集合,可以添加任意類型的數據,在后期運行代碼時,進行類型轉換就會出問題。
如果我們使用了泛型,那么在添加數據時,如果添加的數據類型不對,編譯就會出問題,更不用說后期運行了。
所以我們用一句話總結泛型:
泛型主要是將運行期間的異常問題,轉移到編譯期間來體現,避免了類型強制轉換的問題。
闖關練習
需求:創建一個指定泛型為Integer的Set集合,添加數字1到100,取出里面的偶數。
答案:
public class GenericsDemo3 {
public static void main(String[] args) {
//1.創建一個泛型為Integer的集合
Set<Integer> numbers = new HashSet<Integer>();
//2.向set集合中添加數字:1-100
for (int i = 1; i <=100 ; i++) {
numbers.add(i);
}
//3.遍歷set集合,獲取里面的偶數并打印
for (Integer elementData : numbers) {
//4.條件判斷:
if(elementData%2==0){
//5.打印測試:
System.out.println("偶數是:"+elementData);
}
}
}
}
開班時間:2021-04-12(深圳)
開班盛況開班時間:2021-05-17(北京)
開班盛況開班時間:2021-03-22(杭州)
開班盛況開班時間:2021-04-26(北京)
開班盛況開班時間:2021-05-10(北京)
開班盛況開班時間:2021-02-22(北京)
開班盛況開班時間:2021-07-12(北京)
預約報名開班時間:2020-09-21(上海)
開班盛況開班時間:2021-07-12(北京)
預約報名開班時間:2019-07-22(北京)
開班盛況Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號