简体   繁体   English

如何使用反射调用一个在可变参数中包含 null 的方法

[英]How to use Reflection Invoke a method which contain null in varargs

I'm in the situation like a class contains the same method name, and we are trying to use reflection to call, but it's seemed to have an issue when one of the argument contains null我的情况是一个类包含相同的方法名称,并且我们正在尝试使用反射来调用,但是当其中一个参数包含 null 时似乎有问题

For example :例如 :


package test;

public class Invoker {
    public void test(String a, Integer b) {
        System.out.println("String, Integer");
    }

    public void test(Integer a, Integer b) {
        System.out.println("Integer, Integer");
    }

    public void invoke(String methodName, Object ...args) {
        try {
           Class<?>[] clazz = new Class[args.length];
            int i=0;
           for(Object a:args) {
               clazz[i++] = a != null ? a.getClass() : null;
           }

           Method m = this.getClass().getMethod(methodName, clazz);

           // ... Continue for invocation

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String ...args) {
        Invoker invoker = new Invoker();

        // happened to be null sometimes
        String a = null;
        Integer b = 123;

        System.out.println("Trigger Normally");
        invoker.test(a, b);

        System.out.println("Trigger via Reflection");
        invoker.invoke("test", a, b);
    }
}

Result结果

Trigger Normally
String, Integer
Trigger via Reflection
java.lang.NoSuchMethodException: test.Invoker.test(null, java.lang.Integer)
    at java.lang.Class.getMethod(Class.java:1678)
    at test.Invoker.invoke(Invoker.java:21)
    at test.Invoker.main(Invoker.java:42)

The Argument sometimes happened to be null, but if it is null, It will trigger NoSuchMethodException Argument 有时碰巧为空,但如果为空,则会触发NoSuchMethodException

Our method name not intended to be unique, it has to be overload structure.我们的方法名称不是唯一的,它必须是重载结构。

Due to early binding the overloaded method being called is determined at compile time (or if it can't be determined, you'll get a compile-time error).由于早期绑定,被调用的重载方法是在编译时确定的(或者如果无法确定,则会出现编译时错误)。 Since you have String a = null , the compiler can determine that you want to call test(String, Integer) .由于您有String a = null ,编译器可以确定您要调用test(String, Integer)

Your reflection call is happening at runtime and missing type information from your null parameter (the method doesn't know it originated from a String a , the compiler knew that at compile time, but this is runtime), so you need to provide information whether it's a null String or Integer .您的反射调用发生在运行时,并且您的null参数中缺少类型信息(该方法不知道它源自String a ,编译器知道在编译时,但这是运行时),因此您需要提供信息它是一个空StringInteger

If you want to have your reflection method work with null values (and overloaded methods), you would need to add a separate type parameter to use in case of nulls.如果您想让反射方法使用空值(和重载方法),则需要添加一个单独的类型参数以在空值的情况下使用。 For example例如

invoker.invoke("test", a, String.class, b, Integer.class);

You can't get it to work for nulls without additional type information, since it would be like invoking test(null, 1) .如果没有额外的类型信息,你就不能让它为空值工作,因为它就像调用test(null, 1) The compiler needs your help in this case too, eg test((Integer)null, 1) or test((String)null, 1) , try it out.在这种情况下,编译器也需要您的帮助,例如test((Integer)null, 1)test((String)null, 1) ,尝试一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM