1. 程式人生 > >Java 泛型萬用字元解釋

Java 泛型萬用字元解釋

前言
最近看Rxjava retrofit 中到處都是泛型型別定義,不得不重新整理一下資料,簡單介紹,滿足基本理解使用。

定義什麼是泛型?

泛型,即“引數化型別”。一提到引數,最熟悉的就是定義方法時有形參,然後呼叫此方法時傳遞實參。那麼引數化型別怎麼理解呢?顧名思義,就是將型別由原來的具體的型別引數化,類似於方法中的變數引數,此時型別也定義成引數形式(可以稱之為型別形參),然後在使用/呼叫時傳入具體的型別(型別實參)。

一 java萬用字元 <T>,<E>,<K,V>,<?>

使用"<T>"來宣告型別持有者名稱,自定義泛型類時,類持有者名稱可以使用T(Type),如果是容器的元素可以使用E(Element),若鍵值匹配可以用K(Key)和V(Value)等,若是<?>

,則是預設是允許Object及其下的子類,也就是java的所有物件了。

二 泛型型別限制寫法上下界

Java上界萬用字元  <? extends Fruit>
Java 下界萬用字元  <? super Fruit>
Eg:

上界萬用字元
public static void upMethod(List<? extends Fruit> list){
//編譯報錯
//使用萬用字元後,不能在往集合類中新增元素
//list.add(); //使用萬用字元後,是可以取出元素的
//所有取出的元素,都是上界父類元素
Fruit fruit = list.get(0);
}

 下界萬用字元
public
static void downMethod(List<? super Fruit> list){ //下界萬用字元可以往容器內新增元素 //但是有限制,必須是Fruit的子類或者本身,父類是新增不進去的 list.add(new Apple()); //取出元素的型別都為Object Object object = list.get(0); }
class Box<T> {

     private T data;

     public Box() {

     }

     public Box(T data) {
         this.data = data;
     }

     public
T getData() { return data; } }

裡面所有 T 標識,表示接收外部傳遞型別引數

Eg: new Box<String>();  new Box( “ 我是泛型T”)
  裡面的<T> 表示String型別

泛型方法

不帶返回值
public Box(T data) {
         this.data = data;
     }
帶返回值
Public T Box(T data) {
        Return data;
     }

Eg:

    public final static <T> Observable<T> create(OnSubscribe<T> f) {
        return new Observable<T>(hook.onCreate(f));
}

這裡檢視Rxjava泛型方法定義

  public final static <T> Observable<T> create(OnSubscribe<T> f) {
        return new Observable<T>(hook.onCreate(f));
    }
  1. 泛型方法必須加標識
  2. Observable 泛型返回型別
  3. OnSubscribe f 泛型T的型別
  4. f 泛型型別

泛型引數

Box(T data)

說明一下,定義泛型方法時,必須在返回值前邊加一個,來宣告這是一個泛型方法,持有一個泛型T,然後才可以用泛型T作為方法的返回值。
OnSubscribe的作用就是指明泛型的具體型別,而OnSubscribe型別的變數t,可以用來建立泛型類的物件。
當然,泛型方法不是僅僅可以有一個引數OnSubscribe,可以根據需要新增其他引數。
為什麼要使用泛型方法呢?因為泛型類要在例項化的時候就指明型別,如果想換一種型別,不得不重新new一次,可能不夠靈活;而泛型方法可以在呼叫的時候指明型別,更加靈活。

定義泛型方法語法格式如下:

這裡寫圖片描述

呼叫泛型方法語法格式如下:

這裡寫圖片描述