2

我正在寻找一种方法来提取 Java 中签名的本质。原因是我想在我的 java.lang.reflect.Proxies 的 Map 中使用签名作为唯一键。

使用此代码:

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()andmethod.getParameterTypes()是否就足够了,或者我应该使用method.getTypeParameters()andmethod.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,并且在使用代理时遇到了问题,因为我丢失了通用信息。

我切换到使用名称、returnType 和 parameterTypes,它工作正常......

我也考虑过使用 declaringClass 但我删除了它并且不记得我是如何做到的......

于 2009-10-21T10:03:44.947 回答