1. 程式人生 > >Java泛型知識點整理

Java泛型知識點整理

泛型的最大好處是避免了類轉化異常(ClassCastException)的發生

為什麼要使用泛型

要寫一個表示座標的類,可以有3種格式,int,float,String,為了避免寫3個類,統一可以寫成下面的格式

<span style="font-size:14px;font-weight: normal;">class Point{
	private Object x ;		// 表示X座標
	private Object y ;		// 表示Y座標
	public void setX(Object x){
		this.x = x ;
	}
	public void setY(Object y){
		this.y = y ;
	}
	public Object getX(){
		return this.x ;
	}
	public Object getY(){
		return this.y ;
	}
};

public class GenericsDemo01{
	public static void main(String args[]){
		Point p = new Point() ;	// 宣告一個Point的物件
		p.setX(10) ;		// 利用自動裝箱操作:int --> Integer --> Object
		p.setY(20) ;		// 利用自動裝箱操作:int --> Integer --> Object
		int x = (Integer)p.getX() ;	// 取出資料先變為Integer,之後自動拆箱
		int y = (Integer)p.getY() ;	// 取出資料先變為Integer,之後自動拆箱
		System.out.println("整數表示,X座標為:" + x) ;
		System.out.println("整數表示,Y座標為:" + y) ;
	}
};</span>
但是還是容易造成型別轉化異常,比如p.setY("東經120度"),int y=(Integer)p.getY();



泛型的應用

而上面的例子如果寫成這樣,就通用了

<pre name="code" class="java">class Point<T>{		// 此處可以隨便寫識別符號號,T是type的簡稱
	private T var ;	// var的型別由T指定,即:由外部指定
	public T getVar(){	// 返回值的型別由外部決定
		return var ;
	}
	public void setVar(T var){	// 設定的型別也由外部決定
		this.var = var ;
	}
};
public class GenericsDemo06{
	public static void main(String args[]){
		Point<String> p = new Point<String>() ;	// 裡面的var型別為String型別
		p.setVar("字串") ;		// 設定字串
		System.out.println(p.getVar().length()) ;	// 取得字串的長度
	}
};

多個泛型

class Notepad<K,V>{		// 此處指定了兩個泛型型別
	private K key ;		// 此變數的型別由外部決定
	private V value ;	// 此變數的型別由外部決定
	public K getKey(){
		return this.key ;
	}
	public V getValue(){
		return this.value ;
	}
	public void setKey(K key){
		this.key = key ;
	}
	public void setValue(V value){
		this.value = value ;
	}
};
public class GenericsDemo09{
	public static void main(String args[]){
		Notepad<String,Integer> t = null ;		// 定義兩個泛型型別的物件
		t = new Notepad<String,Integer>() ;		// 裡面的key為String,value為Integer
		t.setKey("李興華") ;		// 設定第一個內容
		t.setValue(30) ;			// 設定第二個內容
		System.out.print("姓名;" + t.getKey()) ;		// 取得資訊
		System.out.print(",年齡;" + t.getValue()) ;		// 取得資訊

	}
};


泛型的安全警告

<span style="font-size:14px;font-weight: normal;">class Info<T>{
	private T var ;
	public T getVar(){
		return this.var ;
	}
	public void setVar(T var){
		this.var = var ;
	}
	public String toString(){		// 覆寫Object類中的toString()方法
		return this.var.toString() ;
	}
};
public class GenericsDemo10{
	public static void main(String args[]){
		Info i = new Info() ;		// 警告,沒有指定泛型型別
		i.setVar("字串") ;			// 設定字串
		System.out.println("內容:" + i.getVar()) ;
	}
};</span>

萬用字元

<span style="font-weight: normal;"><span style="font-size:14px;">class Info<T>{
	private T var ;		// 定義泛型變數
	public void setVar(T var){
		this.var = var ;
	}
	public T getVar(){
		return this.var ;
	}
	public String toString(){	// 直接列印
		return this.var.toString() ;
	}
};
public class GenericsDemo14{
	public static void main(String args[]){
		Info<String> i = new Info<String>() ;		// 使用String為泛型型別
		i.setVar("字串") ;				// 設定內容
		fun(i) ;
	}
	public static void fun(Info<?> temp){		// 可以接收任意的泛型物件
		System.out.println("內容:" + temp) ;
	}
};</span></span>
<span style="font-size:14px;font-weight: normal;">class Info<T>{
	private T var ;		// 定義泛型變數
	public void setVar(T var){
		this.var = var ;
	}
	public T getVar(){
		return this.var ;
	}
	public String toString(){	// 直接列印
		return this.var.toString() ;
	}
};
public class GenericsDemo17{
	public static void main(String args[]){
		Info<Integer> i1 = new Info<Integer>() ;		// 宣告Integer的泛型物件
		Info<Float> i2 = new Info<Float>() ;			// 宣告Float的泛型物件
		i1.setVar(30) ;									// 設定整數,自動裝箱
		i2.setVar(30.1f) ;								// 設定小數,自動裝箱
		fun(i1) ;
		fun(i2) ;
	}
	public static void fun(Info<? extends Number> temp){	// 只能接收Number及其Number的子類
		System.out.print(temp + "、") ;
	}
};</span>

<span style="font-size:14px;font-weight: normal;">class Info<T extends Number>{	// 此處泛型只能是數字型別
	private T var ;		// 定義泛型變數
	public void setVar(T var){
		this.var = var ;
	}
	public T getVar(){
		return this.var ;
	}
	public String toString(){	// 直接列印
		return this.var.toString() ;
	}
};
public class GenericsDemo19{
	public static void main(String args[]){
		Info<Integer> i1 = new Info<Integer>() ;		// 宣告Integer的泛型物件
	}
};</span>

泛型與子類的繼承的限制

<span style="font-weight: normal;"><span style="font-size:14px;">class Info<T>{
	private T var ;		// 定義泛型變數
	public void setVar(T var){
		this.var = var ;
	}
	public T getVar(){
		return this.var ;
	}
	public String toString(){	// 直接列印
		return this.var.toString() ;
	}
};
public class GenericsDemo21{
	public static void main(String args[]){
		Info<String> i1 = new Info<String>() ;		// 宣告String的泛型物件
		Info<Object> i2 = new Info<Object>() ;		// 宣告Object的泛型物件
		i1.setVar("hello") ;
		i2.setVar(new Object()) ;
		fun(i1) ;
		fun(i2) ;
	}
	public static void fun(Info<? super String> temp){	// 只能接收String或Object型別的泛型
		System.out.print(temp + "、") ;
	}
};</span></span>

泛型介面
<span style="font-size:14px;font-weight: normal;">interface Info<T>{		// 在介面上定義泛型
	public T getVar() ;	// 定義抽象方法,抽象方法的返回值就是泛型型別
}
class InfoImpl<T> implements Info<T>{	// 定義泛型介面的子類
	private T var ;				// 定義屬性
	public InfoImpl(T var){		// 通過構造方法設定屬性內容
		this.setVar(var) ;	
	}
	public void setVar(T var){
		this.var = var ;
	}
	public T getVar(){
		return this.var ;
	}
};
public class GenericsDemo24{
	public static void main(String arsg[]){
		Info<String> i = null;		// 宣告介面物件
		i = new InfoImpl<String>("字串") ;	// 通過子類例項化物件
		System.out.println("內容:" + i.getVar()) ;
	}
};</span>


泛型方法
<span style="font-size:14px;font-weight: normal;">class Info<T>{	// 指定上限,只能是數字型別
	private T var ;		// 此型別由外部決定
	public T getVar(){
		return this.var ;	
	}
	public void setVar(T var){
		this.var = var ;
	}
	public String toString(){		// 覆寫Object類中的toString()方法
		return this.var.toString() ;	
	}
};
public class GenericsDemo28{
	public static void main(String args[]){
		Info<String> i1 = new Info<String>() ;
		Info<String> i2 = new Info<String>() ;
		i1.setVar("HELLO") ;		// 設定內容
		i2.setVar("字串") ;		// 設定內容
		add(i1,i2) ;
	}
	public static <T> void add(Info<T> i1,Info<T> i2){
		System.out.println(i1.getVar() + " " + i2.getVar()) ;
	}
};</span>


泛型陣列
public class GenericsDemo30{
	public static void main(String args[]){
		Integer i[] = fun1(1,2,3,4,5,6) ;	// 返回泛型陣列
		fun2(i) ;
	}
	public static <T> T[] fun1(T...arg){	// 接收可變引數
		return arg ;			// 返回泛型陣列
	}
	public static <T> void fun2(T param[]){	// 輸出
		System.out.print("接收泛型陣列:") ;
		for(T t:param){
			System.out.print(t + "、") ;
		}
	}
};