簡體   English   中英

Java反射:在運行時檢查方法參數的類型

[英]Java reflection: Checking the type of the method parameter at runtime

我需要檢查方法第一個參數的類型是List<Class<? extends Exception>> List<Class<? extends Exception>>或不。 任何人都可以提出比將其與String相比更好的解決方案嗎?

Method m = Foo.class.getMethod("m1", List.class);
if (m.getGenericParameterTypes()[0].toString().equals("java.util.List<java.lang.Class<? extends java.lang.Exception>>")) {
  ...
}

我的意思是這樣的:

List.class.isAssignableFrom((Class<?>)((ParameterizedType)m.getGenericParameterTypes()[0]).getRawType()));

這檢查它是否是一個列表。 但我如何檢查Class<? extends Exception> Class<? extends Exception>類型的一部分?

剛剛試過以下,它似乎工作:

// package whatever.your.package.happens.to.be;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.WildcardType;
import java.util.List;

public class ReflectionTest {
  public static void main(String[] args) throws NoSuchMethodException, SecurityException {
    Method method = ReflectionTest.class.getMethod("method", List.class);
    ParameterizedType listType = (ParameterizedType)method.getGenericParameterTypes()[0];
    ParameterizedType classType = (ParameterizedType)listType.getActualTypeArguments()[0];
    WildcardType genericType = (WildcardType)classType.getActualTypeArguments()[0];
    Class<?> genericClass = (Class<?>)genericType.getUpperBounds()[0];

    boolean isException = Exception.class.isAssignableFrom(genericClass);
    // vvv Prints out "Is Class<? extends Exception>: true"
    System.out.println("Is Class<? extends Exception>: " + isException);

    boolean isRuntimeException = RuntimeException.class.isAssignableFrom(genericClass);
    // vvv Prints out "Is Class<? extends RuntimeException>: false"
    System.out.println("Is Class<? extends RuntimeException>: " + isRuntimeException);
  }

  public void method(List<Class<? extends Exception>> exceptionClasses) {
    // Do something with "exceptionClasses," I would imagine...
  }
}

編輯:好的,這次是實時的。 剛才注意到它是List<Class<? extends Exception>> List<Class<? extends Exception>>而不是List<? extends Exception> List<? extends Exception> 所以這個(希望)最終的解決方案實際上應該符合這個案例。

編輯:

問:如何從參數參數中讀取上限?

例如,我們將使用方法描述

public void testMethod(Collection<? extends Exception);

首先我們必須訪問方法參數的參數

 ParametrizedType parametrizedType = (ParametrizedType)method.getGenericParametersTypes()[0];

從這個parametrizedType我們必須得到它的參數:

Type argumentOfargument  parametrizedType.getActualTypeArguments()[0];

到目前為止一切順利,現在我們需要檢查這個argumentOfargument是一個通配符。

if(arguemntOfargument instaceof WildcardType) {
   WidlcardType wildcardArgumentofArgumentType = (WidlcardType )argumentOfargument;  
}

在這一點上,我們有兩個選項:

  return  wildcardArgumentofArgumentType.getUpperBounds()[0]

或更低:

  return  wildcardArgumentofArgumentType.getLowerBounds()[0]

我認為在Type Erasure之后你可以獲得那種信息。

如果你不知道它是如何工作的,請查看官方文檔: Java類型擦除

簡而言之,當編譯器解釋您的代碼時,它會清除所有通用信息並用有界參數替換它們,如果它們沒有綁定,則用Object替換它們。

但是,您可以使用instanceof運算符來檢查Exception類型。

編輯:如果要在實際調用方法之前檢查參數,可以嘗試使用代理模式。 詳細信息: 代理模式

你需要它專門List<Class<? extends Exception>> List<Class<? extends Exception>> ,或者是超類型(例如Collection<Class<? extends Exception>> ,甚至是Object )好嗎? 我問,因為你提到isAssignableFrom ,它尋找一個子類型 - 超類型關系。

如果您正在尋找子類型 - 超類型關系,那么您可以執行類似Random Human描述的操作。

如果您正在尋找完全匹配,那么您應該能夠使用equals :反射API中的各種類和接口指定了equals友好定義。 例如, ParameterizedType

實現此接口的類的實例必須實現equals()方法,該方法等同於共享相同泛型類型聲明且具有相同類型參數的任何兩個實例。

當然,這需要在List<Class<? extends Exception>>某個地方有一些例子List<Class<? extends Exception>> List<Class<? extends Exception>>參數,您可以獲取其類型並執行equals比較。

(但說實話, toString方法,雖然是hackish,但對我來說看起來並不壞!)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM