天天看點

Java基礎學習筆記 - 泛型

    泛型是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;
    }
}
           

    上述代碼運作,會報類型轉換錯誤:

Java基礎學習筆記 - 泛型

    泛型的好處是在編譯的時候檢測類型安全,并且所有的強制轉換都是自動和隐式的,提高代碼的重用率。如下,改成下面的代碼,便不需要作強制轉換。

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);
    }
}
           

    運作結果:

Java基礎學習筆記 - 泛型