首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 反射獲取泛型資訊完整指南:參數與回傳值型別解析

     編輯:Java 綜合教學

Java 反射獲取泛型資訊完整指南:參數與回傳值型別解析

Java 泛型在編譯期經過型別擦除,執行期無法直接獲取泛型參數。但透過反射 API 中的 ParameterizedType 與 Type 介面,我們仍能在特定情境下(方法參數、回傳值、欄位宣告)完整保留並獲取泛型資訊。本文透過實戰程式碼詳細示範。

核心類別與介面

  • Type:所有型別的公共介面
  • ParameterizedType:參數化型別(如 List<String>)
  • Method.getGenericParameterTypes():獲取方法泛型參數型別
  • Method.getGenericReturnType():獲取方法泛型回傳型別

實戰程式碼示範

package com.coscon.reflectionTest;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class ReflectionForGenerics {
    // 測試方法:帶泛型參數
    public void test01(Map<String, User> map, List<User> users) {
        System.out.println("test01");
    }

    // 測試方法:帶泛型回傳值
    public Map<Integer, User> test02() {
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("com.coscon.reflectionTest.ReflectionForGenerics");

            // 1. 獲取方法參數泛型資訊
            Method method = clazz.getMethod("test01", Map.class, List.class);
            Type[] types = method.getGenericParameterTypes();
            
            for (Type type : types) {
                System.out.println("#" + type);
                if (type instanceof ParameterizedType) {
                    Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
                    for (Type typeArg : actualTypeArguments) {
                        System.out.println("泛型參數型別:" + typeArg);
                    }
                }
            }

            System.out.println("--------------------------------------------------------------");

            // 2. 獲取方法回傳值泛型資訊
            Method method2 = clazz.getMethod("test02");
            Type returnType = method2.getGenericReturnType();
            System.out.println("#" + returnType);
            
            if (returnType instanceof ParameterizedType) {
                Type[] typeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
                for (Type typeArg : typeArguments) {
                    System.out.println("回傳值泛型型別:" + typeArg);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

執行結果分析

#java.util.Map<java.lang.String, com.coscon.reflectionTest.User>
泛型參數型別:class java.lang.String
泛型參數型別:class com.coscon.reflectionTest.User
#java.util.List<com.coscon.reflectionTest.User>
泛型參數型別:class com.coscon.reflectionTest.User
--------------------------------------------------------------
#java.util.Map<java.lang.Integer, com.coscon.reflectionTest.User>
回傳值泛型型別:class java.lang.Integer
回傳值泛型型別:class com.coscon.reflectionTest.User

關鍵點總結

  1. 僅特定位置保留泛型:方法簽名、欄位宣告、類別繼承關係會保留泛型資訊,區域變數則會被擦除
  2. 判斷 ParameterizedType:使用 instanceof 判斷後強制轉型,再呼叫 getActualTypeArguments()
  3. 巢狀泛型處理:如 Map<String, List<User>> 需遞迴解析每一層 Type

應用場景

  • 框架開發:自動化資料綁定、序列化/反序列化
  • ORM 框架:根據泛型型別自動映射資料庫欄位
  • API 文檔生成:提取介面泛型簽名生成文檔

總結

掌握反射獲取泛型資訊的技巧,是開發高階框架與工具的關鍵能力。雖然 Java 型別擦除機制限制了執行期泛型的完整可用性,但透過 ParameterizedType 仍能在關鍵位置獲得完整型別資訊,為泛型程式設計提供強大支援。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved