9

メソッドの最初のパラメーターの型が であるかどうかを確認する必要がありますList<Class<? extends Exception>>。それを文字列と比較するよりも良い解決策を提案できる人はいますか?

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>タイプの部分を確認できますか?

4

4 に答える 4

5

次のことを試しただけで、うまくいくようです:

// 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<? extends Exception>

于 2012-07-18T14:17:43.423 に答える
1

編集:

Q: パラメータ引数から上限を読み取る方法は?

たとえば、メソッドの説明を使用します

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;  
}

この時点で、 upper には 2 つのオプションがあります。

  return  wildcardArgumentofArgumentType.getUpperBounds()[0]

またはより低い場合:

  return  wildcardArgumentofArgumentType.getLowerBounds()[0]
于 2012-07-18T14:19:29.993 に答える
0

Type Erasure の後は、そのような情報を取得できると思います。

それがどのように機能するかがわからない場合は、公式ドキュメントを確認してください: Java type eraser

つまり、コンパイラがコードを解釈すると、すべての一般的な情報がクリアされ、それらがバインドされたパラメーターまたはObjectバインドされていない場合に置き換えられます。

instanceofただし、演​​算子を使用してExceptionタイプを確認できます。

編集:実際にメソッドを呼び出す前にパラメーターを確認したい場合は、プロキシ パターンを使用してみてください。詳細はこちら:プロキシ パターン

于 2012-07-18T14:01:34.757 に答える
0

具体的に である必要がありますList<Class<? extends Exception>>か、それともスーパータイプ ( Collection<Class<? extends Exception>>、または など) でも問題ありObjectませんか? isAssignableFromサブタイプとスーパータイプの関係を検索する について言及されているため、お尋ねします。

サブタイプとスーパータイプの関係を探している場合は、Random Human で説明されているようなことを行うことができます。

完全に一致するものを探している場合は、 を使用できるはずです。equalsリフレクション API のさまざまなクラスとインターフェイスは、 のわかりやすい定義を指定しますequals。たとえば、次のようにParameterizedType述べています

このインターフェイスを実装するクラスのインスタンスは、同じジェネリック型宣言を共有し、等しい型パラメーターを持つ任意の 2 つのインスタンスを同等にする equals() メソッドを実装する必要があります。

もちろん、これには、型を取得して比較List<Class<? extends Exception>>を実行できるパラメーターの例がどこかにある必要があります。equals

(しかし、正直なところ、このtoStringアプローチはハックですが、私にはそれほど悪くはありません!)

于 2012-07-18T14:27:42.373 に答える