2

Javaで署名の本質を抽出する方法を探しています。その理由は、java.lang.reflect.Proxiesのマップで一意のキーとして署名を使用したいためです。

このコードで:

public interface MyInterface {
  public int compute(String s);
}

...
public static void main (String... args) throws Exception {
  InvocationHandler handler = ...;
  MyInterface i = (MyInterface) Proxy.newProxyInstance(
      Beans.class.getClassLoader(),
      new Class<?>[] { MyInterface.class },
      handler);

  Method m1 = MyInterface.class.getMethod("compute", String.class);
  Method m2 = i.getClass().getMethod("compute", String.class);
  System.out.printf("%b%f", m1.equals(m2));
}

結果は明らかに誤りです。

このコードは、InvocationHandler内で必要になるため、使用するコードではありませんが、プロキシの実装とインターフェイスに関して、取得method.getName()してmethod.getParameterTypes()十分か、それとも使用する必要があるかどうか疑問に思っています。method.getTypeParameters()method.getParameterAnnotations()

要するに:インターフェースとそのjava.lang.reflect.Proxy実装で同じメソッドシグネチャを取得する方法は?

4

3 に答える 3

3

Method私はあなたが渡されたいと思いますInvocationHandler

package playtest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import static junit.framework.Assert.*;

interface MyInterface {
    void run();
    void about();
    void run(String j);
}


public class TestProxyClass {
    @Test
    public void testDeclaringClass() throws Exception {
        final Map<Method, Runnable> actions = new HashMap<Method, Runnable>();

        actions.put(MyInterface.class.getMethod("run"), new Runnable() {

            @Override
            public void run() {
                System.out.println("run");
            }

        } );
        actions.put(MyInterface.class.getMethod("run", String.class), new Runnable() {

            @Override
            public void run() {
                System.out.println("run string");
            }

        } );
        actions.put(MyInterface.class.getMethod("about"), new Runnable() {

            @Override
            public void run() {
                System.out.println("about");
            }

        } );

        MyInterface face = (MyInterface) Proxy.newProxyInstance(getClass().getClassLoader(), 
                new Class<?>[] { MyInterface.class }, new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        actions.get(method).run();
                        return null;
                    }

                } );

        face.run();
        face.about();
        face.run("Hello");
    }
}
于 2009-10-21T09:52:51.897 に答える
1

の結果をMethod.toGenericStringキーとして使用するのはどうですか?返される文字列には、私が知る限り、署名のすべての詳細が含まれています。

役に立つかもしれないもう一つのことは:Method m2 = i.getClass().getMethod("compute", String.class).getDeclaringClass().getMethod("compute", String.class);。その結果、m1.equals(m2)trueが返される可能性があります。

于 2009-10-21T09:20:50.457 に答える
0

これを行うコードにバグがあり、name、genericReturnType、genericParameterTypesを取得しました。また、汎用情報が失われたため、プロキシを操作するときに問題が発生しました。

name、returnType、parameterTypesを使用するように切り替えましたが、正常に動作します...

declaringClassの使用も検討しましたが、削除したので、これをどのように行ったか正確に覚えていません...

于 2009-10-21T10:03:44.947 に答える