1. 程式人生 > 其它 >Java反射學習筆記:getParameterTypes和getGenericParameterTypes區別

Java反射學習筆記:getParameterTypes和getGenericParameterTypes區別

環境

Java:1.8
Intellij IDEA:2019.2.4

前言

最近在寫匯出程式,對getGenericParameterTypes和getParameterTypes兩個方法的區別產生了好奇。

區別

這兩個方法都是用來獲取方法形參型別的。

getGenericParameterTypes:返回Type型別的陣列 Type[].
getParameterTypes:返回Class型別的陣列: Class<?>[].

Type是一個高階介面;具體的說明來看一段網上的解釋:

Type 是所有型別的高階公共介面,當然也是Class的父類。
它們包括原始型別、引數化型別、陣列型別、型別變數和基本型別。

先來看一下Type 的用法:
①type是一種表示程式語言中的所有型別的類超級介面:
如:int、Integer、String 這都是表示一程式語言的型別,而其中的 int.class、Integer.class、String.class 它們表示的是型別的例項。

②我們以前學習的反射 Class c = Integer.class,Class相當於表示型別的類,而Integer.class 則是一種名為整形型別的型別例項。

③理解了上面的那些,其理解 type就不難了,type 與 class 一樣,不過 type是一種比Class 表示範圍還要廣的超級介面,它表示Java語言中型別的所有介面。

示例程式碼

首先假設有這麼一個類:SampleClass

這個類有兩個屬性,一個String型別,一個泛型List

import java.util.List;
public class SampleClass {
    private String sampleField;
    private List<Integer> ids;
    public String getSampleField() {
        return sampleField;
    }
    public void setSampleField(String sampleField) {
        this.sampleField = sampleField;
    }
    public List<Integer> getIds() {
        return ids;
    }
    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }
}

然後寫測試程式碼:

public static void main(String[] args) {
        Class sampleClassClass = SampleClass.class;
        Method[] methods = sampleClassClass.getMethods();
        for (Method method : methods) {
            System.out.println("------------------" +method.getName());
            Type[] genericParameterTypes = 
            method.getGenericParameterTypes();
            Class<?>[] parameterTypes = method.getParameterTypes();
            for(Class parameterType: parameterTypes){
                System.out.println(parameterType + "===="+
                parameterType.getName());
            }
            for (int i = 0; i < genericParameterTypes.length; i++) {
                System.out.println(genericParameterTypes[i] + 
                "=====" + genericParameterTypes[i].getTypeName());
            }
        }

執行結果如下:

① String型別,這兩個方法返回的結果是一樣的
② List ,getParameterTypes 只返回了型別,泛型沒有返回;
而getGenericParameterTypes返回的是完整的泛型。

結論

①如果方法引數不是引數化型別(泛型),那麼getParameterTypes和getGenericParameterTypes返回的結果是一樣的。
②如果方法引數是泛型,這時就有區別了,getGenericParameterTypes會返回完整的資訊,而getParameterTypes只會返回引數型別,引數化型別無法得到。

獲取引數化型別
// 將型別向引數化型別轉換
ParameterizedType t = (ParameterizedType)genericParameterTypes[0];
// 可以得到引數化型別的引數例項
t.getActualTypeArguments()[0];

參考地址:
反射得到引數化型別中的型別引數

https://www.yiibai.com/javareflect/javareflect_method_getgenericparametertypes.html

https://www.yiibai.com/javareflect/javareflect_method_getparametertypes.html
————————————————
本文轉自Java反射學習筆記:getParameterTypes和getGenericParameterTypes區別