第三次學JAVA再學不好就喫翔(part82)--泛型

學習筆記,僅供參考

收集的泛型Blog:泛型


泛型


泛型的概述


  • 泛型概述
    • 通常而言我們只會使用容器來存儲一種類型的對象。泛型的主要目的之一就是用來指定容器要持有什麼類型的,因此與其使用Object,我們更喜歡暫時不指定類型,而是稍後再決定具體使用什麼類型。要達到這個目的,需要使用類型參數,用尖括號括住,放在類名後面。然後在使用這個類的時候,再用實際的類型替換此類型參數。
  • 泛型好處
    • 提高安全性(將運行期的錯誤轉換到編譯期)
    • 省去強轉的麻煩
  • 泛型基本使用
    • <>中放的必須是引用數據類型

舉個例子


我在ArrayList中放多種數據類型,代碼如下:

package com.guiyang.restudy3;

import java.util.ArrayList;
import java.util.Iterator;

import com.guiyang.bean.Person;

public class D1Genric {

	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add(110);
		list.add(true);
		list.add(new Person("張三", 23));
		list.add(new Person("李四", 24));
		
		Iterator it = list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

輸出:

110
true
Person [name=張三, age=23]
Person [name=李四, age=24]

現在,我想調用集合中元素的getName方法。由於,Person的父類Object類中不存在getName方法,所以我們需要對元素進行強制向下轉型:

package com.guiyang.restudy3;

import java.util.ArrayList;
import java.util.Iterator;

import com.guiyang.bean.Person;

public class D1Genric {

	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add(110);
		list.add(true);
		list.add(new Person("張三", 23));
		list.add(new Person("李四", 24));
		Iterator it = list.iterator();
		while(it.hasNext()) {
			Person p = (Person)it.next();			
			System.out.println(p.getName() + "..." + p.getAge());
		}	
	}
}

報錯信息:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to com.guiyang.bean.Person
	at com.guiyang.restudy3.D1Genric.main(D1Genric.java:19)

ClassCastException異常,是JVM在檢測到兩個類型間轉換不兼容時引發的運行時異常。


在上面的代碼中,我們引發了ClassCastException異常,這是由於我們試圖對Integer強制轉換爲Person類時發生的異常,這個異常在編譯時沒有顯露出來。

如果我想讓這個錯誤在編譯階段就暴露,我就需要用到泛型,規定只有Person類及其子類可以進入ArrayList:

ArrayList<Person> list = new ArrayList<Person>();

當我們給ArrayList加上泛型之後,Java就會提示我們出現了編譯時錯誤:

我們把這倆行代碼刪除後,再運行:

package com.guiyang.restudy3;

import java.util.ArrayList;
import java.util.Iterator;

import com.guiyang.bean.Person;

public class D1Genric {

	public static void main(String[] args) {
		ArrayList<Person> list = new ArrayList<Person>();
		list.add(new Person("張三", 23));
		list.add(new Person("李四", 24));
		
		Iterator<Person> it = list.iterator();
		while(it.hasNext()) {
			Person p = it.next();
			//由於我們利用泛型獲取到的都是Person對象,所以就可以不用向下強轉了
			System.out.println(p.getName() + "..." + p.getAge());
		}
	}
}

輸出:

張三...23
李四...24

  • 注意事項

前後泛型必須一致,下面,我們分別列出了正確的和錯誤的寫法:

//正確的(前後一致)
ArrayList<Person> list = new ArrayList<Person>();
//錯誤的(前後不一致)
ArrayList<Person> list = new ArrayList<Object>();

當我們在前面定義過泛型之後,後面的泛型可以不定義,若定義了,則前後必須一致:

//正確的(前定義,後不定義)
ArrayList<Person> list = new ArrayList<>();

最後,注意泛型最好不要定義爲Object,不會報錯,但是沒意義:

//沒意義
ArrayList<Object> list = new ArrayList<>();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章