Java泛型程序設計之定義簡單泛型類、泛型方法、以及類型變量的限定

在學習使用泛型定義一個簡單的類之前,首先需要嘮嗑幾句關於泛型的幾個概述:

1:從Java程序設計語言1.0版發佈以來,變化最大的部分就是泛型。

2:使用泛型機制編寫的程序代碼要比那些雜亂的使用Object變量,然後在進行強制類型轉換的的代碼具有更好的安全性和可讀性。

3:泛型程序設計意味着編寫的代碼可以被很多不同類型的對象所重用。

4:在Java中增加泛型類之前,泛型程序設計是用繼承實現的,使用這種方法有兩個問題:當獲取一個值時必須進行強制類型轉換;此外這裏也沒有錯誤檢查,也就是說可以向數組列表中添加任何類的對象。

5:泛型通過提供一個類型參數,用來指示元素類型,從而解決了使用繼承實現泛型的弊端,使得程序具有更好的可讀性和安全性。

好了,以上就是關於泛型的最基本的概述,下面正式敘述一下如何定義和使用一個簡單的泛型類

一個泛型類就是具有一個或多個類型變量的類

下面是一個例子:

package GenericProgramma;

public class PairTest1 {
	public static void main(String[] args) {
		String[] words= {"Mary","had","a","little","lamb"};
		Pair<String> mm=ArrayAlg.minmax(words);
		System.out.println("min="+mm.getFirst());
		System.out.println("max="+mm.getSecond());
	}
}

class Pair<T>{
	private T first;
	private T second;
	
	public Pair() {
		first=null;
		second=null;
	}
	
	public Pair(T first,T second) {
		this.first=first;
		this.second=second;
	}
	
	public T getFirst() {
		return first;
	}
	
	public T getSecond() {
		return second;
	}
	
	public void setFirst(T newValue) {
		first=newValue;
	}
	
	public void setSecond(T newValue) {
		second=newValue;
	}
}

class ArrayAlg{
	public static Pair<String> minmax(String[] a){
		if(a==null || a.length==0) {
			return null;
		}
		String min=a[0];
		String max=a[0];
		for(int i=0;i<a.length;++i) {
			if(min.compareTo(a[i])>0) {
				min=a[i];
			}
			if(max.compareTo(a[i])<0) {
				max=a[i];
			}
		}
		return new Pair<>(min,max);
	}
}

上面這個程序從一個字符數組中找出最小和最大的字符串,並且以Pair類型返回,其中Pair就是一個簡單的泛型類。

下面,我麼來分析一下泛型類應該如何寫:

Pair類引入了一個類型變量T,用尖括號(<>)括起來,並放在類名後面,泛型類可以有多個泛型變量。例如,可以將Pair類定義成以下形式:class Pair<T,U>{...}

類定義中的類型變量指定方法的返回類型以及域和局部變量的類型。如private  T first;

用具體的類型替換類型變量就可以實例化泛型類型,例如:Pair<String>

有一點需要注意:類型變量使用大寫形式,且比較短,這是很常見的。在庫中,使用變量E表示集合的元素類型。K和V分別表示表的關鍵字與值的類型,T(需要時還可以用臨近的字母U和S)表示任意類型。


以上是關於泛型類的定義和使用,下面就介紹關於泛型方法的定義和使用

也是首先觀察一個示例:

package Generic;

import java.util.Arrays;

public class PairTest2 {
	public static void main(String[] args) {
		Integer[] testInt=new Integer[] {1,2,3,4,5,6,7};
		System.out.println(Arrays.toString(testInt));
		testInt=ArrayAlg.swap(testInt, 2, 34);
		//這是完整寫法
		//testInt=ArrayAlg.<Integer>swap(testInt, 2, 3);
		//一般情況下省略類型參數不會出現問題,但是如果傳入
		//參數,,編譯器不足以推斷出類型時就會出現錯誤
		System.out.println(Arrays.toString(testInt));
	}
}

class ArrayAlg{
	//用於交換傳入數組的兩個下標的值
	public static <T> T[] swap(T[] t,int index1,int index2) throws IndexOutOfBoundsException{
		try {
			T temp=t[index1];
			t[index1]=t[index2];
			t[index2]=temp;
		}catch(IndexOutOfBoundsException e) {
			throw e;
		}
		return t;
	}
}

首先我們發現,這個泛型方法並不是在泛型類中定義的,也就是說,泛型方法不一定非得定義在泛型類中。

下面介紹一下詳細規則:

類型變量(尖括號中的變量)放在修飾符的後面,返回類型的前面。

當調用一個泛型方法時,在方法名前的尖括號中放入具體的類型。(有時候也可以省略)

最後,是關於類型變量的限定

同樣地,先上例子:

package Generic;

public class PairTest3 {
	public static void main(String[] args) {
		Integer[] testInt=new Integer[] {1,2,6,5,7,3,2,1};
		System.out.println(ArrayAlg.findMax(testInt));
	}
}

class ArrayAlg{
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T extends Comparable> T findMax(T[] a) throws IndexOutOfBoundsException{
		T temp=a[0];
		for(T t:a) {
			if(t.compareTo(temp)>0)temp=t;
		}
		return temp;
	}
}
觀察上面程序,我們使用了extends關鍵字,意思就是,只有實現了Comparable接口的類纔可以使用這個泛型方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章