2

getDeclaredMethod()このシグネチャを持つメソッドを見つけるために使用したい:

public void foo(String inArg1, Object... inArgs);

この呼び出しの使用:

Class<?>[] argClasses = { String.class, Integer.class };
Method m = clazz.getDeclaredMethod("foo", argClasses);

しかし、それはNoSuchMethodException例外を生成します。ただし、メソッドを呼び出すことは可能です (別の方法で見つけたと仮定します)。

Object[] args = { "arg1", new Integer(2) };
m.invoke(instance, args);

を使用してそれらをすべてリストし、getDeclaredMethods()自分で署名の照合を試みることもできますが、それは大変な作業のようです。

私がやりたいことは可能であるべきですか?私は何かばかげたことを見逃していますか?

4

4 に答える 4

5

vararg 引数は、配列のシンタックス シュガーにすぎません。メソッドのシグネチャは

foo(String, Object[]);

そしてそうではない

foo(String, Integer);
于 2012-12-24T13:44:07.470 に答える
3

foo メソッドを見つける唯一の正当な方法は、

Class<?>[] argClasses = { String.class, Object[].class };
Method m = clazz.getDeclaredMethod("foo", argClasses);

はどうかと言うと

Object[] args = { "arg1", new Integer(2) };
m.invoke(instance, args);

リフレクションなしで foo を呼び出すのと同じように、それは非常に合法です

foo("str", new Integer(2));
于 2012-12-24T14:00:02.693 に答える
2

このメソッドは、オブジェクトを受け入れるように宣言されているため、任意のオブジェクトで呼び出すことができます。- ただし、型で宣言されているため、正確に宣言された型を検索しないと、via を見つけることができません。ObjectgetDeclaredMethod()

ただし、宣言されたすべてのメソッドを反復処理し、それらのパラメーターの型をチェックして、指定した型から割り当て可能かどうかを確認し、パラメーターで呼び出し可能なすべてのメソッドを見つけることができるはずです。

例:

Class[] signature = {String.class, Integer.class};
Method[] methods = someClass.getDeclaredMethods();

for ( Method m : methods ) {
  Class[] params = m.getParameterTypes();
  if ( params.length == signature.length ) {
    int i;
    for ( i = 0; i < signature.length && params[i].isAssignableFrom( signature[i] ); i++ ) {

    }
    if ( i == signature.length ) {
      System.out.println("Found matching method: " + m.getName());
    }
  }
}

ただし、Object...実際にどのタイプから割り当て可能かは確認していません。Integer可変引数がInteger[]配列にコンパイルされるため、そうではないと思います。

于 2012-12-24T14:08:41.337 に答える