1. 程式人生 > >java新特性—泛型

java新特性—泛型

泛型genericity

泛型就是指類中的屬性的型別在例項化物件的時候通過外部進行了指定。

class 類名稱<泛型型別,泛型型別,…>{
}

一個泛型的小程式。

package org.study.RobertChao;

public class Info<T>{
    private T x;//x屬性的型別由外部決定
    private T y;//y屬性的型別由外部決定
    public T getX(){
        return x;
    }
    public void setX(T x){
        this
.x = x; } public T getY(){ return y; } public void setY(T y){ this.y = y; } }

宣告一個具有封裝性的類,其中的屬性的型別由外部決定,屬於泛型。

package org.study.RobertChao;

public class GenDemo00{
    public static void main(String[] args){
        Info<Integer> i= new Info<Integer>();
        i.setX(11
); i.setY(20); int x = i.getX();//取出x int y = i.getY();//取出y System.out.println("x是:"+ x); System.out.println("y是:"+ y); } }

在設定X、Y的引數型別的時候,要求與例項化物件的型別一致。

package org.study.RobertChao;

public class GenDemo01{
public static void main(String[] args){
    Info<Integer> i= new
Info<Integer>(); i.setX(11);//正確,與<T>的型別要保持一致。 i.setY("二十");//錯誤,不能設定String型別。 int x =i.getX();//取出x。 int y =i.getY();//取出y。 System.out.println("x是:"+x); System.out.println("y是:"+y); } }

1、在構造方法上引用泛型。

package org.study.RobertChao;

public class Info<T>{
    private T x;//x屬性的型別由外部決定
    private T y;//y屬性的型別由外部決定

    public Info(T x, T y){
        this.setX(x);
        this.setY(y);
    }//在構造方法中使用泛型,寫在引數的構造器中作為引數。

    public T getX(){
        return x;
    }
    public void setX(T x){
        this.x = x;
    }
    public T getY(){
        return y;
    }
    public void setY(T y){
        this.y = y;
    }
}
package org.study.RobertChao;

public class GenDemo02 {
    public static void main(String[] args) {
    Info<Integer> i= new Info<Integer>(10, 20);
    //在呼叫的時候需要使用構造方法設定內容。
    //設定的內容本身依然由泛型指定。
    int x = i.getX();//取出x
    int y = i.getY();//取出y
    System.out.println("x是:"+x);
    System.out.println("y是:"+y);
    }
}

通過上述的結論可以知道:

  • 型別名稱<型別> 變數名稱=new 型別名稱<型別>(符合構造器的內容)
  • 無參構造器Info<Integer> i=new Info<Integer>();
  • 有引數的構造器Info<Integer> i=new Info<Integer>(10, 20);

2、擦除泛型。

擦出泛型:使用的時候沒有指定泛型的話。

  • 泛型擦除之後,將按照Object進行接收,以保證程式不出現任何的錯誤。

  • Infop = new Info(10, 20);

  • 使用泛型的樣式是:
    • Info<Integer> i=new Info<Integer>(10, 20);

3、萬用字元。

  • "?"
    • “?”表示的是可以接收任意的泛型型別。
    • 只是接收輸出,並不能修改。
package org.study.RobertChao;

public class GenDemo03{
    public static void main(String[] args) {
        Info<Object> i1 = new Info<Object>();
        Info<Integer> i2 = new Info<Integer>();
        fun(i1) ;
        fun(i2) ;
    }
    public static void fun(Info<?> in){
    //表示,此時可以接收任意的型別
        System.out.println(in.getX());
        System.out.println(in.getY());
    }
}
  • 泛型上限extends

    • 語法:"? extends 父類"

    • 所包含的最大的內容就是父類的內容。

    • 父類是Number,能夠接收到的型別是Number及其子類Integer、etc..

    • 泛型的上限也可以在方法上使用,例如:接受引數。

package org.study.RobertChao;

public class GenDemoup04 {
    public static void main(String[] args) {
        Info<Integer> in= new Info<Integer>();
        fun(in);
    }
    public static void fun((Point<? extends Number> in)){
    //表示,此時可以接收任意的型別
        System.out.println(in.getX());
        System.out.println(in.getY());
    }
}
  • 泛型下限super

    • 語法:"? super 父類"

    - 只能設定其具體的類或者父類。

    • 泛型的下限也可以在方法上使用,例如:接受引數。
package org.study.RobertChao;

public class GenDemodown04 {
    public static void main(String[] args) {
        Info<Integer> in= new Info<Integer>();
        fun(in);
    }
    public static void fun((Point<? super Number>po)){
    //表示,此時可以接收任意的型別
        System.out.println(in.getX());
        System.out.println(in.getY());
    }
}

4、泛型介面

  • 公式 interface 介面名稱<泛型型別,泛型型別,…>{}

泛型介面的定義:

package org.study.RobertChao;

public interface Demo<T>{//定義泛型介面
    public void print(T param);//此抽象方法中使用了泛型型別
}

泛型介面定義完成,後需要定義子類實現此介面。

實現的方法有兩種:

  • The first.

  • GenDemo05繼承了Demo,通過例項化的時候分配的型別決定。

package org.study.RobertChao;

public class GenDemo05<T> implements Demo<T> {
    public void print(T param){
        System.out.println("param = "+param);
    }
}
package org.study.RobertChao;

public class GenDemo06{
    public static void main(String[] args) {
        Demo<String> demo = new GenDemo05<String>() ;
        demo.print("hello") ;
    }
}
  • The Second.

  • 這種方法在類中,一早就輸入了合適的型別。

package org.study.RobertChao;

public class GenDemo07 implements Demo<GenDemo07>{
//設定具體型別
    public void print(GenDemo07 param){
        System.out.println("param = "+param);
    }
}
package org.study.RobertChao;

public class GenDemo08{
    public static void main(String[] args) {
        Demo<GenDemo07> demo = new GenDemo07() ;
        demo.print(new GenDemo07()) ;
    }
}

5、泛型方法

  • 泛型除了在類中,還可以在方法上使用泛型。
  • 此方法所在的類不一定是泛型的操作類。
package org.study.RobertChao;
public class Demo09{
    public <T> T print(T param){//定義泛型方法
    //第一個 <T> 表示該方法是泛型方法。
    //第二個  T  表示返回值型別是T型別。
        return param;
    }
}
  • Demo類中的print()方法裡面接收泛型的型別,而且此方法的返回值也是指定的泛型型別。

可以將方法的返回值定義成一個泛型的陣列。

package org.study.RobertChao;
    public class GenDemo10{
        public static void main(String[] args){
            Integer i[] = fun(1, 2, 3, 4, 5, 6, 7, 8, 9);
            for (int x : i){
                System.out.println(x);
            }
        }
        public static <T> T[] fun(T... param){
            return param; // 返回陣列
        }
}

6、泛型巢狀
|- 用一個例子來說明巢狀,(容器裡邊存放容器)

// 泛型類Info<K,V>  
class Info<K,V>{  
    private K key;  
    private V value;  

   // 建構函式  
    public Info(K key, V val){  
        this.key = key;  
       this.value = val;     
    }     

    // 設定key  
    public void setKey(K k){  
        this.key = k;     
    }  

   // 設定value  
    public void setValue(V v){  
      this.value = v;   
    }  

    // 獲取KEY  
    public K getKey(){  
     return this.key;    
    }  

    // 獲取value  
    public V getValue(){  
        return this.value;        
    }  

    // 覆寫toString()方法  
    public String toString(){  
        return "Key:"+this.key+", Value:"+this.value;  
   }  
}  

// Demo<S>中的S在這代表Info<K,V>,實現泛型巢狀  
class Demo<S>{  
    // 泛型S的物件  
    private S info;  

    // Demo建構函式  
    public Demo(S info) {  
        this.info = info;     
    }  

   // 設定S型別的info  
    public void setInfo(S info){  
        this.info = info;     
    }  

    // 獲取info  
    public S getInfo(){  
        return this.info;     
    }  
}  
// main  
public class GenericEmbeded{  
   public static void main(String args[]){  

        // 例項化Info類物件  
       Info<String,Integer> info = new Info<String, Integer>("石家莊",1);  
        // 例項化Demo類物件,泛型巢狀 
       Demo<Info<String,Integer>> d = new Demo< Info<String,Integer>>(info);  
        // 獲取Info<K,V>物件後,再呼叫toString()方法,最後輸出.  
        System.out.print(d.getInfo());                      
    }     
}