範型方法 & 範型參數 & 範型返回值

Java範型類html

public class FanXingClassTest {
    public static void main(String args[]){
        Test<Integer> intObj = new Test<Integer>(123);
        Test<String> strObj = new Test<String>("一二三");
        intObj.showType();
        strObj.showType();
    }
}

/**
 * 定義範型類
 * @param <T>
 */
class Test<T>{
    private T ob; //定義範型的成員變量

    public Test(T ob){
        this.ob = ob;
    }

    public void setT(T ob){
        this.ob = ob;
    }
    public T getT(){
        return this.ob;
    }

    public void showType(){
        System.out.println("T的實際類型是:"+ob.getClass());
    }
}

  對比一下沒有使用範型類(以下代碼),也能夠輸出同樣的結果,爲何要使用範型類?類型檢查??this

public class FanXingClassTest {
    public static void main(String args[]){
        Test intObj = new Test(123);
        Test strObj = new Test("一二三");
        intObj.showType();
        strObj.showType();
    }
}
/**
 * 定義普通類
 */
class Test{
    private Object ob; // 不能定義T類型的變量??

    public Test(Object ob){
        this.ob = ob;
    }

    public void setT(Object ob){
        this.ob = ob;
    }
    public Object getT(){
        return this.ob;
    }

    public void showType(){
        System.out.println("T的實際類型是:"+ob.getClass());
    }
}

咱們作實驗以下:spa

// 兩個基本類:StringDemo和DoubleDemo
public class StringDemo {
    private String str;

    public StringDemo(String str){
        this.str = str;
    }

    public void setStr(String str){
        this.str = str;
    }
    public String getStr(){
        return this.str;
    }
}
public class DoubleDemo {
    private Double doubleVal;

    public DoubleDemo(Double doubleVal){
        this.doubleVal = doubleVal;
    }
    public void setDoubleVal(Double doubleVal){
        this.doubleVal = doubleVal;
    }
    public Double getDoubleVal(){
        return this.doubleVal;
    }
}

// 由於上面的類中,成員和方法的邏輯都同樣,就是類型不同,所以考慮重構。Object是全部類的父類,所以能夠考慮用Object作爲成員類型,這樣就能夠實現通用了,實際上就是「Object泛型」,暫時這麼稱呼。
public class ObjectDemo {
    private Object obj;

    public ObjectDemo(Object obj){
        this.obj = obj;
    }
    public void setObj(Object obj){
        this.obj = obj;
    }
    public Object getObj(){
        return this.obj;
    }
}
public class MyDemo {
    public static void main(String args[]){
        ObjectDemo str = new ObjectDemo("string");
        ObjectDemo dble = new ObjectDemo(123d);
        ObjectDemo obj = new ObjectDemo(new Object());
        System.out.println(str.getObj());
        System.out.println(dble.getObj());
        System.out.println(obj.getObj());
    }
}

// 在Java 5以前,爲了讓類有通用性,每每將參數類型、返回類型設置爲Object類型,當獲取這些返回類型來使用時候,必須將其「強制」轉換爲原有的類型或者接口,
// 而後才能夠調用對象上的方法。強制類型轉換很麻煩,我還要事先知道各個Object具體類型是什麼,才能作出正確轉換。不然,要是轉換的類型不對,好比將
// 「Hello Generics!」字符串強制轉換爲Double,那麼編譯的時候不會報錯,但是運行的時候就掛了。那有沒有不強制轉換的辦法----有,改用 Java5泛型來實現,
// 示例見最上面FanXingClassTest<T>範型類的定義。

範型類語法解釋3d

1. 使用<T>來聲明一個類型持有者名稱,而後就能夠把T看成一個類型表明來聲明成員、參數和返回值類型。
2. class GenericsTest<T> 聲明瞭一個泛型類,這個T沒有任何限制,實際上至關於Object類型,實際上至關於 class GenericsTest<T extends Object>。
3. 與Object泛型類相比,使用泛型所定義的類在聲明和構造實例的時候,可使用「<實際類型>」來一併指定泛型類型持有者的真實類型。類如
GenericsTest<Double> douTest=new GenericsTest<Double>(new Double("33"));
4. 實際上,當構造對象時不指定類型信息的時候,默認會使用Object類型,這也是要強制轉換的緣由.

限制範型code

  在上面的例子中,因爲沒有限制class GenericsTest<T>類型持有者T的範圍,實際上這裏的限定類型至關於Object,這和「Object泛型」實質是同樣的。限制好比咱們要限制T爲集合接口類型。只須要這麼作:class GenericsTest<T extends Collection>,這樣類中的泛型T只能是Collection接口的實現類,傳入非Collection接口編譯會出錯。注意:<T extends Collection>這裏的限定使用關鍵字extends,後面能夠是類也能夠是接口。但這裏的extends已經不是繼承的含義了,應該理解爲T類型是實現Collection接口的類型,或者T是繼承了XX類的類型。
// 限制範型
public class CollectionGenTest<T extends Collection> {
    private T x;
    public CollectionGenTest(T x){
        this.x = x;
    }
    public T getX(){
        return this.x;
    }
    public void setX(T x){
        this.x = x;
    }
}
public class CollectionGenTestDemo {
    public static void main(String args[]){
        CollectionGenTest<ArrayList> test = new CollectionGenTest<ArrayList>(new ArrayList());
        System.out.println("實例化完成");
    }
}

// 多接口限制
<T extends SomeClass & interface1 & interface2 & interface3>

// 通配符範型
<T extends Collection> //向下限制
<?> //任意類型,至關於Object
<T super Double> // 向上限制,Double類型或者其父類

Java範型方法htm

 

/**
 * 範型方法:只需在返回值前添加<T>
 */
public class ExampleA {
    public <T> void f(T x){
        System.err.println(x.getClass().getName());
    }

    public static void main(String args[]){
        ExampleA exampleA = new ExampleA();
        exampleA.f("");
        exampleA.f(123);
        exampleA.f('a');
        exampleA.f(exampleA);
    }
}

// 使用泛型方法時,沒必要指明參數類型,編譯器會本身找出具體的類型。泛型方法除了定義不一樣,調用就像普通方法同樣
// 一個static方法,沒法訪問泛型類的類型參數,因此,若要static方法須要使用泛型能力,必須使其成爲泛型方法。

 

方法對象

 1. 定義泛型方法時,必須在返回值前邊加一個<T>,來聲明這是一個泛型方法,blog

2. Class<T>的做用就是指明泛型的具體類型,而Class<T>類型的變量c,能夠用來建立泛型類的對象。爲何要用變量c來建立對象呢?既然是泛型方法,就表明着咱們不知道具體的類型是什麼,也不知道構造方法如何,所以沒有辦法去new一個對象,但能夠利用變量c的newInstance方法去建立對象,也就是利用反射建立對象。繼承

 3.   http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html接口

相關文章
相關標籤/搜索