泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操作的資料類型被指定為一個參數。這種參數類型可以用在類、接口和方法的建立中,分别稱為泛型類、泛型接口、泛型方法。
Java語言引入泛型的好處是安全簡單。
在Java SE 1.5之前,沒有泛型的情況下,通過對類型Object的引用來實作參數的“任意化”,“任意化”帶來的缺點是要做顯示的強制類型轉換,而這種轉換是要求開發者對實際參數類型可以預知的情況下進行的。對于強制類型轉換錯誤的情況,編譯器不提示錯誤,在運作的時候才會出現異常,這是一個安全隐患。隐患示例如下:
import java.util.*;
public class Test25_1 {
public static void main(String[] args) {
ArrayList al = new ArrayList();
// 建立一隻狗,并存放到集合中
Dog dog1 = new Dog("旺财", 2);
al.add(dog1);
//從集合中取出
Dog temp1 = (Dog)al.get(0); //此處一定需要作強制轉換,否則編譯報錯
Cat temp2 = (Cat)al.get(0); //此處編譯不會報錯,但是運作時會報類型轉換錯誤
}
}
class Dog
{
private String name;
private int age;
public Dog(String name, int age)
{
this.name = name;
this.age = age;
}
}
class Cat
{
private String name;
private String color;
public Cat(String name, String color)
{
this.name = name;
this.color = color;
}
}
上述代碼運作,會報類型轉換錯誤:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0DNXlVMshVWxgmMihGbHVWdW12Yw50MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3kTN2QTOyIDMzETOwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
泛型的好處是在編譯的時候檢測類型安全,并且所有的強制轉換都是自動和隐式的,提高代碼的重用率。如下,改成下面的代碼,便不需要作強制轉換。
public static void main(String[] args) {
ArrayList<Dog> al = new ArrayList<Dog>(); //使用泛型
// 建立一隻狗,并存放到集合中
Dog dog1 = new Dog("旺财", 2);
al.add(dog1);
//從集合中取出
Dog temp1 = al.get(0); //無需強制轉換
Cat temp2 = al.get(0); //編譯報錯
}
通過泛型反射機制,可以獲得類的很多資訊,比如類的名稱、類的函數名稱、函數的傳回類型等。
import java.util.*;
import java.lang.reflect.*;
public class Test25_1 {
public static void main(String[] args) {
Gen<Integer> gen1 = new Gen<Integer>(1);
gen1.showTypeName();
Gen<String> gen2 = new Gen<String>("apple");
gen2.showTypeName();
Gen<Bird> gen3 = new Gen<Bird>(new Bird());
gen3.showTypeName();
gen3.showMethodName();
}
}
//定義一個泛型類
class Gen<T>
{
private T o;
// 構造函數
public Gen(T t)
{
o = t;
}
// 通過反射機制,得到T類型的名稱
public void showTypeName()
{
System.out.println("類型是:"+o.getClass().getName());
}
// 通過反射機制,得到T類型的成員函數名稱
public void showMethodName()
{
Method[] m = o.getClass().getDeclaredMethods();
for (int i = 0; i<m.length; i++)
{
System.out.println("函數名是:"+m[i].getName());
}
}
}
class Bird{
public void test1()
{
System.out.println("Bird class");
}
public void count(int a, int b)
{
System.out.println(a+b);
}
}
運作結果: