15

私はインタープリターを介したコードの動的呼び出しに取り組んでおり、JLS セクション 15.12で説明されているように、メソッド解決の厄介な領域に取り組んでいます。

メソッドを選択する「簡単な」方法は、すべての引数の正確な型を知っている場合です。その時点でClass.getDeclaredMethod(String name, Class[] parameterTypes). メソッドのアクセシビリティとクラスのスーパークラス/スーパーインターフェースを確認する必要があるかもしれません。

ただし、これは次のケースのいずれもカバーしていないため、役に立ちません。

  • ボックス化/ボックス化解除プリミティブ
  • サブタイプ
  • 可変引数
  • null 引数 (インタープリターが別の方法で認識していない限り、任意の型にすることができます。コンパイル時に null をクラス/インターフェイスにキャストすることにより、あいまいさが解消されます)
  • プリミティブ型変換 (Java の一部ではありませんが、言語のコンテキストでは許容されます。たとえば、Rhino Javascript ではすべての数値が浮動小数点であるため、Java コードは an を取る可能性がありますintが、呼び出し元は anintまたは a のいずれかの数値を渡しますdouble)

(最初の 3 つの簡単な例については、以下を参照してください)

そのため、独自のメソッド解決ライブラリを作成する必要があります...

これを支援する有名なフレームワーク ライブラリはありますか?

package com.example.test.reflect;

import java.lang.reflect.Method;

public class MethodResolutionTest {
    public void compute(int i)              { /* implementation... */ }
    public void compute(Long l)             { /* implementation... */ }
    public void compute(Object obj)         { /* implementation... */ }
    public void compute(String... strings)  { /* implementation... */ }

    public static void main(String[] args) {
        Class<?> cl = MethodResolutionTest.class;

        /* these succeed */
        findAndPrintMethod(cl, "compute", int.class);
        findAndPrintMethod(cl, "compute", Long.class);
        findAndPrintMethod(cl, "compute", Object.class);
        findAndPrintMethod(cl, "compute", String[].class);

        /* these fail */
        findAndPrintMethod(cl, "compute", Integer.class);
        findAndPrintMethod(cl, "compute", long.class);
        findAndPrintMethod(cl, "compute", MethodResolutionTest.class);
        findAndPrintMethod(cl, "compute", String.class, String.class);
    }
    private static void findAndPrintMethod(Class<?> objectClass, 
            String methodName, Class<?>... parameterTypes) 
    {
        try {
            Method method = findMethod(objectClass, methodName, 
                   parameterTypes);
            System.out.println(method.toString());
        }
        catch (SecurityException e) {
            e.printStackTrace();
        }
        catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    private static Method findMethod(Class<?> objectClass, 
            String methodName, Class<?>[] parameterTypes) 
        throws SecurityException, NoSuchMethodException 
    {
        return objectClass.getDeclaredMethod(methodName, parameterTypes);
    }
}
4

4 に答える 4

3

このブログ投稿を読み、 ClassMateを確認してください。それはあなたのために汚れた仕事のほとんどをするべきです。

于 2011-05-17T09:52:21.903 に答える
2

Commons beanutilsには、一致するメソッドを見つけるための次の関数があります 。getMatchingAccessibleMethod

プリミティブ型で動作しますが、ドキュメントに記載されているように、多少不確定です。

于 2011-05-16T22:53:36.643 に答える
0

guava-discuss のユーザーの 1 人が、Mirror ライブラリを見ることを勧めました。

残念ながら、少なくとも現時点では、オーバーロードの解決も処理しません。

于 2011-05-20T16:35:23.520 に答える
-1

私は MVEL とプロパティである程度成功しましたが、メソッド呼び出しをディスパッチできるかどうか思い出せません。

ただし、まったく別の言語を探している可能性があります。問題の性質を考えると、Java と非常にきれいに統合されている Groovy を検討することをお勧めします。

于 2011-05-16T22:13:07.560 に答える