2

次のプログラムを実行すると:

class Runit{
    public static void main(String[] argsWut) throws Exception {
        String arg = "what?";
        Class[] parameters = { new Object().getClass() };
        Object[] args = { arg };
        System.out.println("".getClass().getMethod("equals",parameters).invoke("what?",args));
    }
};

コマンドラインで次のように表示されます。

true

一方、パラメーター行を少し変更すると、次のようになります。

class Runit{
    public static void main(String[] argsWut) throws Exception {
        String arg = "what?";
        Class[] parameters = { arg.getClass() }; // changed a little here so it's a bit more dynamic --
        Object[] args = { arg };
        System.out.println("".getClass().getMethod("equals",parameters).invoke("what?",args));
    }
};

私は得る:

Exception in thread "main" java.lang.NoSuchMethodException: java.lang.String.equals(java.lang.String)
    at java.lang.Class.getMethod(Class.java:1605)
    at test.Runit.main(Runit.java:7)

getMethodこの1つの例から、メソッドが正確なパラメーターでのみ機能するように見えます。「最適な」メソッドを取得する方法はありますか? たとえば、完全一致が存在する場合はそのメソッドを返しますが、完全一致が存在しない場合は、指定された引数を受け入れることができる任意のメソッドを返すことができます。

4

3 に答える 3

5

Apache Commons Lang MethodUtils クラスには、メソッドのターゲット引数を使用して適切な型を絞り込む "invokeMethod" メソッドがあります (つまり、パラメーターの型を伝える必要はありません)。

これはうまくいくようです:

 System.out.println(MethodUtils.invokeMethod("what?", "equals", new Object[] {"what?"}));

詳細については、javadocs を参照してください: http://commons.apache.org/lang/api/org/apache/commons/lang3/reflect/MethodUtils.html#invokeMethod(java.lang.Object,%20java.lang.String,% 20java.lang.Object ...)

于 2012-06-19T23:09:13.690 に答える
5

Commons BeanUtilsApache ライブラリ、具体的には次のメソッド に興味があるかもしれません: http://commons.apache.org/beanutils/v1.8.0/apidocs/org/apache/commons/beanutils/MethodUtils.html#getMatchingAccessibleMethod%28java.lang.Class, %20java.lang.String,%20java.lang.Class%5b%5d%29

お役に立てれば

于 2012-06-19T23:09:18.860 に答える
3

ドキュメントからgetMethod():

クラス C で一致するメソッドを検索するには: C が、指定された名前とまったく同じ仮パラメーターの型を持つパブリック メソッドを 1 つだけ宣言する場合、それが反映されたメソッドです。そのようなメソッドが C に複数あり、これらのメソッドの 1 つが他のどのメソッドよりも具体的な戻り値の型を持っている場合、そのメソッドが反映されます。それ以外の場合は、いずれかの方法が任意に選択されます。

(私のものを強調します。)

あなたが求めているのは、リフレクションにオーバーロード解決を実行させることです。そして、どうやらそれはありません。この機能が本当に必要な場合は、1) リフレクションの使用をあきらめてメソッドを直接呼び出すか、2) それが不可能な場合は、Java でオーバーロード解決のルールを調べて (ここから開始できます)、使用getMethods()して決定します。使用可能なメソッドを確認してから、オーバーロードの解決を手動で実行します。楽しい時間、私は知っています。

編集他の 回答者が指摘したように、誰かがあなたのためにそれをするためにすでに時間を割いています。涼しい!

于 2012-06-19T23:05:13.353 に答える