Java核心技術第12章(2)
阿新 • • 發佈:2019-02-03
12.3 泛型方法
前面介紹瞭如何定義一個泛型類,實際上,還可以定義一個帶有型別引數的簡單方法.class ArrayAlg
{
public static <T> T getMiddle(T...a)
{
return a[a.length / 2];
}
}
這個方法是在普通類中定義的,而不是在泛型類中定義的.然而,這是一個泛型方法,可以從尖括號和型別變數看出這一點.注意,型別變數放在修飾符(這裡是 public static)的後面,返回型別的前面.泛型方法可以定義在普通類中,也可以定義在泛型類中.
當呼叫一個泛型方法時,在方法名前的尖括號中放入具體的型別:
String middle = ArrayAlg.<String>getMiddle("John", "Q.", "Public");
在這種情況下,方法呼叫中可以省略<String>型別引數.編譯器有足夠的資訊能夠推斷出所呼叫的方法.它用names的型別(即String[])與泛型型別T[]進行匹配並推斷出T一定是String,也就是說,可以呼叫String middle = ArrayAlg.getMiddle("John", "Q.", "Public");
12.4 型別變數的限定
有時,類或方法需要對型別變數加以約束.下面是一個典型的例子.要計算陣列中的最小元素:但是,這裡有一個問題,變數smallest型別為T,這意味著它可以是任何一個類的物件,怎樣才能保證T所屬的類有compareTo方法呢?class ArrayAlg { public static<T> T min(T[] a) // almost correct { if (a == null || a.length == 0) return null; T smallest = a[0]; for (int i = 1; i < a.length; i++) { if (smallest.compareTo(a[i]) smallest = a[i]; } return smallest; } }
解決這個問題的方案似乎將T限制為實現了Comparable介面(只含一個方法compareTo的標準介面)的類.可以通過對型別變數T設定限定實現這一點:
public static <T extends Comparable> T min(T[] a) ...
實際上Comparable介面本身就是一個泛型型別.現在,泛型的min方法只能被實現了Comparable介面的類(如String,Date等)的陣列呼叫.由於Rectangle類沒有實現Comparable介面,所有呼叫min將會產生一個編譯錯誤.
註釋
在此為什麼使用關鍵字 extends 而不是 implements?畢竟Comparable是一個介面.下面的符號:
<T extends BoundingType>
表示T應該繫結型別的子型別(subtype),T和繫結型別可以是類,也可以是介面.選擇關鍵字 extends 的原因是更接近子類的概念.一個型別變數或萬用字元可以有多個限定,例如:
T extends Comparable & Serializable
限定型別用"&"分隔,而逗號用來分隔型別變數.在Java的繼承中,可以根據需要擁有多個介面超型別,但限定中至多有一個類.如果用一個類作為限定,它必須是限定列表中的第一個.
pair2/PairTest2.java如下所示:
package pair2;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class PairTest2
{
public static void main(String[] args)
{
GregorianCalendar[] birthdays =
{
new GregorianCalendar(1906, Calendar.DECEMBER, 9),
new GregorianCalendar(1815, Calendar.DECEMBER, 10),
new GregorianCalendar(1903, Calendar.DECEMBER, 3),
new GregorianCalendar(1910, Calendar.JUNE, 22)
};
Pair<GregorianCalendar> mm = ArrayAlg.minmax(birthdays);
System.out.println("min = " + mm.getFirst().getTime());
System.out.println("max = " + mm.getSecond().getTime());
}
}
class ArrayAlg
{
/**
* Gets the minimum and maximum of an array of objects of type T
* @param a an array of strings
* @return a pair with the min and max value, or null if a is null or empty
*/
public static <T extends Comparable> Pair<T> minmax(T[] a)
{
if (a == null || a.length == 0)
return null;
T min = a[0];
T max = a[0];
for (T element : a)
{
if (min.compareTo(element) > 0) min = element;
if (max.compareTo(element) < 0) max = element;
}
return new Pair<>(min, max);
}
}
執行結果如下所示: