我可以将什么作为第二个参数传递给 java 反射的 getMethod 以表示没有参数?

发布于 2024-12-24 19:25:13 字数 1018 浏览 1 评论 0原文

我正在做一些奇怪的反射工作,以避免将一大堆方法包装在一个类中。 java 文档 建议 null 将是解决方案,但它失败并出现 NoSuchMethodException。

 public Method getMethod(String name,
                         Class[] parameterTypes)
                  throws NoSuchMethodException,
                         SecurityException

如果parameterTypes 为null,则将其视为空数组。

首先,我正在尝试:

private <T> T invokeWrappedFunction(Object instance, String methodName, Object... args) {
    try{
        Method m = instance.getClass().getMethod(methodName, (args == null ? null : args.getClass()));
        return (T) m.invoke(instance, args);
    } catch(Exception e) {
        //This is an example, you're lucky I even acknowledged the exception!
    }
}

现在最终会有很多额外的功能,并且实例不是未知类型,因此我可以对失败等做一些有用的事情。真正的问题是如何让 getMethod 工作?

I'm doing some weird reflection stuff to get around wrapping a whole bunch of methods in a class. The java docs suggest that null would be the solution, but it fails with NoSuchMethodException.

 public Method getMethod(String name,
                         Class[] parameterTypes)
                  throws NoSuchMethodException,
                         SecurityException

If parameterTypes is null, it is treated as if it were an empty array.

To begin with I'm trying:

private <T> T invokeWrappedFunction(Object instance, String methodName, Object... args) {
    try{
        Method m = instance.getClass().getMethod(methodName, (args == null ? null : args.getClass()));
        return (T) m.invoke(instance, args);
    } catch(Exception e) {
        //This is an example, you're lucky I even acknowledged the exception!
    }
}

Now eventually there will be lots of extra functionality in there and instance isn't an unknown type so I can do helpful stuff on failures and such. The real question is how do I get the getMethod working?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浪菊怪哟 2024-12-31 19:25:13

根据评论,我添加了一个答案来说明我的意思。

private <T> T invokeWrappedFunction(Object instance, String methodName, Object... args) {
    Class[] classes = null;
    if (args != null) {
        classes = new Class[args.length];
        for (int i = 0; i < args.length; ++i) {
            classes[i] = args[i].getClass();
        }
    }

    try {
        Method m = instance.getClass().getMethod(methodName, classes);
        return (T) m.invoke(instance, args);
    } catch(Exception e) {
        //This is an example, you're lucky I even acknowledged the exception!
    }
}

不过,这在某些情况下仍然行不通。如果您传入的对象是形式参数类型的子类,它将不起作用。

例如:

interface I {
    void method();
}
class C implements I {
    public void method() {
        ... code ...
    }
}

如果您尝试反映一个期望采用 I 的方法,但您向其传递了 C,则 getMethod(...) 将抛出异常而不是返回您想要的方法,因为 C 不等于 I

Based on the comments I'm adding an answer to illustrate what I mean.

private <T> T invokeWrappedFunction(Object instance, String methodName, Object... args) {
    Class[] classes = null;
    if (args != null) {
        classes = new Class[args.length];
        for (int i = 0; i < args.length; ++i) {
            classes[i] = args[i].getClass();
        }
    }

    try {
        Method m = instance.getClass().getMethod(methodName, classes);
        return (T) m.invoke(instance, args);
    } catch(Exception e) {
        //This is an example, you're lucky I even acknowledged the exception!
    }
}

This still will not work in some cases, though. If the object you're passing in is a subclass of the formal parameter type it will not work.

For example:

interface I {
    void method();
}
class C implements I {
    public void method() {
        ... code ...
    }
}

If you try to reflect a method expecting to take an I but you pass it a C then getMethod(...) will throw an exception instead of returning the method you want because C is not equal to I.

枉心 2024-12-31 19:25:13

我认为您传递了一个 new Class[0];

例如

final static Class[] NO_ARGS = new Class[0];
Method m = Method m = instance.getClass().getMethod(methodName, NO_ARGS);

ADDED

也许我不理解完整的问题。如果问题不是无参数版本。但在 with args 版本中,如果 args 是所有相同类型的数组,则可以处理它。如果它们是不同类型,我想你就有麻烦了。

首先,验证args不为null并且它是一个数组,然后调用Class.getComponentType(),例如

if (args != null) {
   Class c = args.getClass();
   if (c.isArray()) 
      Class arrayClass = c.getComponentType();
   // do something here...
}

I think you pass a new Class[0];

e.g.

final static Class[] NO_ARGS = new Class[0];
Method m = Method m = instance.getClass().getMethod(methodName, NO_ARGS);

ADDED

Maybe I'm not understanding the complete question. If the problem is not the no-args version. but the with args version, you can handle it if the args are an array of all the same type. If they are different types I think you are in trouble.

First, verify that args is not null and that it is an array, then call Class.getComponentType(), e.g.

if (args != null) {
   Class c = args.getClass();
   if (c.isArray()) 
      Class arrayClass = c.getComponentType();
   // do something here...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文