【譯】9. Java反射——泛型

原文地址:http://tutorials.jenkov.com/java-reflection/generics.htmlhtml

========================================================================================java

     我常常在一些文章和論壇中看有人說Java泛型信息都會在編譯時被擦除,因此你不能在運行時訪問任何相關的信息。這也不徹底對。在運行時,在少數狀況下也是能夠訪問到泛型信息的。實際上,這些狀況中已經知足了咱們對Java泛型信息的需求。本文將解釋這幾種狀況。
     下面是本文所涵蓋的主題列表:數組

  1. The Generics Reflection Rule of Thumb ()
  2. Generic Method Return Type (方法返回值類型的泛型)
  3. Generic Method Parameter Types (方法參數類型的泛型)
  4. Generic Field Types (字段類型的泛型)

========================================================================================函數

  • The Generics Reflection Rule of Thumb

     使用Java泛型無外乎就下面兩種狀況中的一種:this

  1. Declaring a class/interface as being parameterizable. (聲明類、接口參數化)
  2. Using a parameterizable class.(使用參數化的類)

     當你寫一個類或者接口的時候,你能夠指定它能夠被參數化。java.util.List接口就是這種用法。你可使java.util.List參數化的建立一個String的列表,而不是建立一個Object的列表。
     當在運行時檢查參數化類型它本身的類型時,如java.util.List,沒有辦法知道它具體被參數化成了什麼類型。這樣也合理,由於在同一應用程序中參數化的類型能夠是全部類型。可是,當你檢查用參數化類型聲明的方法或者字段時,你能夠知道它們在運行時參數化成了什麼類型。簡而言之:
     在運行時,你不會知道參數化類型它本身的類型,可是你能知道用了參數化類型的字段和方法的類型。換句話說,它們有具體的參數類型。
     下面的部分咱們將更進一步的來看這幾種狀況。
========================================================================================spa

  • Generic Method Return Types

     若是你得到了java.lang.reflect.Method對象,你也是有可能得到它的返回值類型的泛型信息的。這不會是任何參數化類型的Method對象,除了在類裏面使用了參數化類型。你能夠去看「Java泛型:方法」來了解如何獲取Method對象。下面是一個例子,類中有參數化返回值類型的返回值:翻譯

public class MyClass {
  protected List<String> stringList = ...;
  public List<String> getStringList(){
    return this.stringList;
  }
}

     在這種狀況下,能夠取得getStringList()方法的泛型返回值類型。換句話說,是能夠檢測到getStringList()方法返回的是List<String>類型而不單單是List。下面是如何來取:代理

Method method = MyClass.class.getMethod("getStringList", null);
Type returnType = method.getGenericReturnType();
if(returnType instanceof ParameterizedType){
    ParameterizedType type = (ParameterizedType) returnType;
    Type[] typeArguments = type.getActualTypeArguments();
    for(Type typeArgument : typeArguments){
        Class typeArgClass = (Class) typeArgument;
        System.out.println("typeArgClass = " + typeArgClass);
    }
}

     這段代碼將會打印出「typeArgClass = java.lang.String」.Type[ ]類型的數組typeArguements中包含一個項——一個表明實現了Type接口的java.lang.String.Class的Class實例。code

========================================================================================htm

  • Generic Method Parameter Types

     在運行時,你也能夠用Java反射機制訪問泛型參數的類型。下面是一個例子,類裏面有一個參數化類型的參數:

public class MyClass {
  protected List<String> stringList = ...;
  public void setStringList(List<String> list){
    this.stringList = list;
  }
}

     你能夠像這樣來訪問其方法參數的參數化類型:

method = Myclass.class.getMethod("setStringList", List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes();
for(Type genericParameterType : genericParameterTypes){
    if(genericParameterType instanceof ParameterizedType){
        ParameterizedType aType = (ParameterizedType) genericParameterType;
        Type[] parameterArgTypes = aType.getActualTypeArguments();
        for(Type parameterArgType : parameterArgTypes){
            Class parameterArgClass = (Class) parameterArgType;
            System.out.println("parameterArgClass = " + parameterArgClass);
        }
    }
}

     這段代碼將會打印出「parameterArgType = java.lang.String」。Type[ ]類型的數組parameterArgTypes中包含一個項——一個表明實現了Type接口的java.lang.String.Class的Class實例。

========================================================================================

  • Generic Field Types

     也能夠訪問公有字段的泛型類型。字段是類的成員變量——要麼是靜態變量,要麼是實體變量。你能夠去看「Java泛型:字段」來了解如何獲取Field對象。下面是一個很早以前的例子,類中有有一個叫stringList的實體字段:

public class MyClass {
  public List<String> stringList = ...;
}
Field field
= MyClass.class.getField("stringList"); Type genericFieldType = field.getGenericType(); if(genericFieldType instanceof ParameterizedType){ ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); for(Type fieldArgType : fieldArgTypes){ Class fieldArgClass = (Class) fieldArgType; System.out.println("fieldArgClass = " + fieldArgClass); } }

     這段代碼將會打印出「fieldArgClass = java.lang.String」。Type[ ]類型的fieldArgTypes數組中包含一個項——一個表明實現了Type接口的java.lang.String.Class的Class實例。

 

 ========================================================================================

 

  • 目錄

 

  這是一個本教程到目前爲止涵蓋的主題列表:     

 

  1. Java反射——引言
  2. Java反射——Class對象
  3. Java反射——構造函數
  4. Java反射——字段
  5. Java反射——方法
  6. Java反射——Getter和Setter
  7. Java反射——私有字段和私有方法
  8. Java反射——註解
  9. Java反射——泛型
  10. Java反射——數組
  11. Java反射——動態代理
  12. Java反射——類的動態加載和從新加載

 

(敬請期待下一篇翻譯)

相關文章
相關標籤/搜索