java 泛型詳解(普通泛型、 通配符、 泛型接口)

一、Java泛型程序員

其實Java的泛型就是建立一個用類型做爲參數的類。就象咱們寫類的方法同樣,方法是這樣的method(String str1,String str2 ),方法中參數str一、str2的值是可變的。而泛型也是同樣的,這樣寫class Java_Generics<K,V>,這裏邊的K和V就象方法中的參數str1和str2,也是可變。數組

編寫泛型類要注意:安全

  1. 在定義一個泛型類的時候,在 「<>」之間定義形式類型參數,例如:「class TestGen<K,V>」,其中「K」 , 「V」不表明值,而是表示類型。性能

  2. 實例化泛型對象的時候,必定要在類名後面指定類型參數的值(類型),一共要有兩次書寫。例如:優化

TestGen<String,String> t=new TestGen<String,String>();this

  1. 泛型中<K extends Object>,extends並不表明繼承,它是類型範圍限制。code

  2. 在實例化對象時不指定泛型,則自動識別爲object。對象

普通泛型繼承

class Point<T>{       // 此處能夠隨便寫標識符號,T是type的簡稱  
    private T var ; // var的類型由T指定,即:由外部指定  
    public T getVar(){  // 返回值的類型由外部決定  
        return var ;  
    }  
    public void setVar(T var){  // 設置的類型也由外部決定  
        this.var = var ;  
    }  
};  
public class GenericsDemo06{  
    public static void main(String args[]){  
        Point<String> p = new Point<String>() ; // 裏面的var類型爲String類型  
        p.setVar("it") ;        // 設置字符串  
        System.out.println(p.getVar().length()) ;   // 取得字符串的長度  
    }  
};  
----------------------------------------------------------  
class Notepad<K,V>{       // 此處指定了兩個泛型類型  
    private K key ;     // 此變量的類型由外部決定  
    private V value ;   // 此變量的類型由外部決定  
    public K getKey(){  
        return this.key ;  
    }  
    public V getValue(){  
        return this.value ;  
    }  
    public void setKey(K key){  
        this.key = key ;  
    }  
    public void setValue(V value){  
        this.value = value ;  
    }  
};  
public class GenericsDemo09{  
    public static void main(String args[]){  
        Notepad<String,Integer> t = null ;        // 定義兩個泛型類型的對象  
        t = new Notepad<String,Integer>() ;       // 裏面的key爲String,value爲Integer  
        t.setKey("湯姆") ;        // 設置第一個內容  
        t.setValue(20) ;            // 設置第二個內容  
        System.out.print("姓名;" + t.getKey()) ;      // 取得信息  
        System.out.print(",年齡;" + t.getValue()) ;       // 取得信息  
  
    }  
};

通配符接口

class Info<T>{  
    private T var ;     // 定義泛型變量  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public String toString(){   // 直接打印  
        return this.var.toString() ;  
    }  
};  
public class GenericsDemo14{  
    public static void main(String args[]){  
        Info<String> i = new Info<String>() ;       // 使用String爲泛型類型  
        i.setVar("it") ;                            // 設置內容  
        fun(i) ;  
    }  
    public static void fun(Info<?> temp){     // 能夠接收任意的泛型對象  
        System.out.println("內容:" + temp) ;  
    }  
};

受限泛型

class Info<T>{  
    private T var ;     // 定義泛型變量  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public String toString(){   // 直接打印  
        return this.var.toString() ;  
    }  
};  
public class GenericsDemo17{  
    public static void main(String args[]){  
        Info<Integer> i1 = new Info<Integer>() ;        // 聲明Integer的泛型對象  
        Info<Float> i2 = new Info<Float>() ;            // 聲明Float的泛型對象  
        i1.setVar(30) ;                                 // 設置整數,自動裝箱  
        i2.setVar(30.1f) ;                              // 設置小數,自動裝箱  
        fun(i1) ;  
        fun(i2) ;  
    }  
    /*只能接收Number及其Number的子類 的泛型
    該方法中只能有讀取,不能寫入,由於你寫入的時候並不清楚具體該泛型究竟是什麼類型,只知道是Numb    er的子類*/
    public static void fun(Info<? extends Number> temp){ 
        System.out.print(temp + "、") ;  
    }  
};  
----------------------------------------------------------  
class Info<T>{  
    private T var ;     // 定義泛型變量  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public String toString(){   // 直接打印  
        return this.var.toString() ;  
    }  
};  
public class GenericsDemo21{  
    public static void main(String args[]){  
        Info<String> i1 = new Info<String>() ;      // 聲明String的泛型對象  
        Info<Object> i2 = new Info<Object>() ;      // 聲明Object的泛型對象  
        i1.setVar("hello") ;  
        i2.setVar(new Object()) ;  
        fun(i1) ;  
        fun(i2) ;  
    }  
    /*只能接收String及其超類的泛型 
    該方法中只能有添加,不能讀,由於你讀的時候並不清楚該泛型具體是什麼類型,只知道是String的超    類,而添加時由於知道了確定是String的超類,就能夠直接將泛型擦除時類型設爲String*/
    public static void fun(Info<? super String> temp){ 
        System.out.print(temp + "、") ;  
    }  
};

泛型沒法向上轉型

class Info<T>{  
    private T var ;     // 定義泛型變量  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public String toString(){   // 直接打印  
        return this.var.toString() ;  
    }  
};  
public class GenericsDemo23{  
    public static void main(String args[]){  
        Info<String> i1 = new Info<String>() ;      // 泛型類型爲String  
        Info<Object> i2 = null ;  
        i2 = i1 ;                               //這句會出錯 incompatible types  
    }  
};

泛型接口

interface Info<T>{        // 在接口上定義泛型  
    public T getVar() ; // 定義抽象方法,抽象方法的返回值就是泛型類型  
}  
class InfoImpl<T> implements Info<T>{   // 定義泛型接口的子類  
    private T var ;             // 定義屬性  
    public InfoImpl(T var){     // 經過構造方法設置屬性內容  
        this.setVar(var) ;    
    }  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
};  
public class GenericsDemo24{  
    public static void main(String arsg[]){  
        Info<String> i = null;        // 聲明接口對象  
        i = new InfoImpl<String>("湯姆") ;  // 經過子類實例化對象  
        System.out.println("內容:" + i.getVar()) ;  
    }  
};  
----------------------------------------------------------  
interface Info<T>{        // 在接口上定義泛型  
    public T getVar() ; // 定義抽象方法,抽象方法的返回值就是泛型類型  
}  
class InfoImpl implements Info<String>{   // 定義泛型接口的子類  
    private String var ;                // 定義屬性  
    public InfoImpl(String var){        // 經過構造方法設置屬性內容  
        this.setVar(var) ;    
    }  
    public void setVar(String var){  
        this.var = var ;  
    }  
    public String getVar(){  
        return this.var ;  
    }  
};  
public class GenericsDemo25{  
    public static void main(String arsg[]){  
        Info i = null;      // 聲明接口對象  
        i = new InfoImpl("湯姆") ;    // 經過子類實例化對象  
        System.out.println("內容:" + i.getVar()) ;  
    }  
};

泛型方法

class Demo{  
    public <T> T fun(T t){            // 能夠接收任意類型的數據  
        return t ;                  // 直接把參數返回  
    }  
};  
public class GenericsDemo26{  
    public static void main(String args[]){  
        Demo d = new Demo() ;   // 實例化Demo對象  
        String str = d.fun("湯姆") ; //   傳遞字符串  
        int i = d.fun(30) ;     // 傳遞數字,自動裝箱  
        System.out.println(str) ;   // 輸出內容  
        System.out.println(i) ;     // 輸出內容  
    }  
};

經過泛型方法返回泛型類型實例

class Info<T extends Number>{ // 指定上限,只能是數字類型  
    private T var ;     // 此類型由外部決定  
    public T getVar(){  
        return this.var ;     
    }  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public String toString(){       // 覆寫Object類中的toString()方法  
        return this.var.toString() ;      
    }  
};  
public class GenericsDemo27{  
    public static void main(String args[]){  
        Info<Integer> i = fun(30) ;  
        System.out.println(i.getVar()) ;  
    }  
    public static <T extends Number> Info<T> fun(T param){//方法中傳入或返回的泛型類型由調用方法時所設置的參數類型決定  
        Info<T> temp = new Info<T>() ;      // 根據傳入的數據類型實例化Info  
        temp.setVar(param) ;        // 將傳遞的內容設置到Info對象的var屬性之中  
        return temp ;   // 返回實例化對象  
    }  
};

使用泛型統一傳入的參數類型

class Info<T>{    // 指定上限,只能是數字類型  
    private T var ;     // 此類型由外部決定  
    public T getVar(){  
        return this.var ;     
    }  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public String toString(){       // 覆寫Object類中的toString()方法  
        return this.var.toString() ;      
    }  
};  
public class GenericsDemo28{  
    public static void main(String args[]){  
        Info<String> i1 = new Info<String>() ;  
        Info<String> i2 = new Info<String>() ;  
        i1.setVar("HELLO") ;        // 設置內容  
        i2.setVar("湯姆") ;       // 設置內容  
        add(i1,i2) ;  
    }  
    public static <T> void add(Info<T> i1,Info<T> i2){  
        System.out.println(i1.getVar() + " " + i2.getVar()) ;  
    }  
};

泛型數組

public class GenericsDemo30{  
    public static void main(String args[]){  
        Integer i[] = fun1(1,2,3,4,5,6) ;   // 返回泛型數組  
        fun2(i) ;  
    }  
    public static <T> T[] fun1(T...arg){  // 接收可變參數  
        return arg ;            // 返回泛型數組  
    }  
    public static <T> void fun2(T param[]){   // 輸出  
        System.out.print("接收泛型數組:") ;  
        for(T t:param){  
            System.out.print(t + "、") ;  
        }  
    }  
};

泛型的嵌套設置

class Info<T,V>{      // 接收兩個泛型類型  
    private T var ;  
    private V value ;  
    public Info(T var,V value){  
        this.setVar(var) ;  
        this.setValue(value) ;  
    }  
    public void setVar(T var){  
        this.var = var ;  
    }  
    public void setValue(V value){  
        this.value = value ;  
    }  
    public T getVar(){  
        return this.var ;  
    }  
    public V getValue(){  
        return this.value ;  
    }  
};  
class Demo<S>{  
    private S info ;  
    public Demo(S info){  
        this.setInfo(info) ;  
    }  
    public void setInfo(S info){  
        this.info = info ;  
    }  
    public S getInfo(){  
        return this.info ;  
    }  
};  
public class GenericsDemo31{  
    public static void main(String args[]){  
        Demo<Info<String,Integer>> d = null ;       // 將Info做爲Demo的泛型類型  
        Info<String,Integer> i = null ;   // Info指定兩個泛型類型  
        i = new Info<String,Integer>("湯姆",30) ;    // 實例化Info對象  
        d = new Demo<Info<String,Integer>>(i) ; // 在Demo類中設置Info類的對象  
        System.out.println("內容一:" + d.getInfo().getVar()) ;  
        System.out.println("內容二:" + d.getInfo().getValue()) ;  
    }  
};

泛型的好處 1,類型安全。 泛型的主要目標是提升 Java 程序的類型安全。經過知道使用泛型定義的變量的類型限制,編譯器能夠在一個高得多的程度上驗證類型假設。沒有泛型,這些假設就只存在於程序員的頭腦中(或者若是幸運的話,還存在於代碼註釋中)。

2,消除強制類型轉換。 泛型的一個附帶好處是,消除源代碼中的許多強制類型轉換。這使得代碼更加可讀,而且減小了出錯機會。

3,潛在的性能收益。 泛型爲較大的優化帶來可能。在泛型的初始實現中,編譯器將強制類型轉換(沒有泛型的話,程序員會指定這些強制類型轉換)插入生成的字節碼中。可是更多類型信息可用於編譯器這一事實,爲將來版本的 JVM 的優化帶來可能。因爲泛型的實現方式,支持泛型(幾乎)不須要 JVM 或類文件更改。全部工做都在編譯器中完成,編譯器生成相似於沒有泛型(和強制類型轉換)時所寫的代碼,只是更能確保類型安全而已。

注意 泛型的聲明,若是在類中沒有聲明泛型,在該類中使用了泛型方法,那麼就在泛型方法中聲明,聲明位置位於返回值前面

相關文章
相關標籤/搜索