反射报错解决 java.lang.IllegalArgumentException: wrong number of arguments

反射报错解决 java.lang.IllegalArgumentException: wrong number of arguments反射调用参数为数组的函数问题 java.lang.IllegalArgumentException: wrong number of arguments 问题背景: UT执行单测遇到报错 java.l

反射调用参数为数组的函数问题

java.lang.IllegalArgumentException: wrong number of arguments

问题背景:

UT执行单测遇到报错 java.lang.IllegalArgumentException: wrong number of arguments

代码

    @Test
    public void test_getAntennaTilt_when_valid_then_return_min_value() {
        AntennaMgrImpl antennaMgr = new AntennaMgrImpl();
        final Method getAntennaTilt = PowerMockito.method(antennaMgr.getClass(), "getAntennaTilt", GainParam[].class);
        getAntennaTilt.setAccessible(true);
        double result = 0d;
        GainParam[] vGains = new GainParam[]{new GainParam()};
        try {
            result = (double) getAntennaTilt.invoke(antennaMgr.getClass(), vGains);
        } catch (InvocationTargetException | IllegalAccessException e) {
            TestCase.fail();
        }
        TestCase.assertEquals(result, 0d);
    }

报错信息

java.lang.IllegalArgumentException: argument type mismatch
​
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at

IDEA编译器提示信息

Confusing argument 'vGains', unclear if a varargs or non-varargs call is desired

解决方法

参数强转为Object

result = (double)getAntennaTilt.invoke(antennaMgr.getClass(), (Object) vGains);

错误原因

当方法签名为数组时,使用反射(或通过mock等其他方式调用反射),注意参数需要将参数强转为Object,原因为invoke方法的签名为可变长参数,编译器无法确认传入的是某一个参数,还是参数列表

反射是运行时获取的,在运行时看来,可变长参数和数组是一致的,因而方法签名为:

//方法签名
([Ljava/lang/String;)V // public void foo(String[] varargs)

当编译器发现类似

method.invoke(object, arg1, arg2) 

这样的表示时,会隐式地创建一个数组,类似new Object [] {arg1, arg2} ,然后将该数组作为invoke方法的参数。 但是如果目标方法的参数本来就是一个数组的时候,如

1 method.invoke(object, Object[]) 

编译器会认为你已经将所有的参数放到数组里面了,从而不会再次包装。于是在这种情况下,作为参数传递给目标方法的,其实是数组里面的元素,而不是数组本身。

总结

当用反射调用方法时,如果目标方法的入参是一个数组,则要把数组包装到另一个Object数组中。

今天的文章反射报错解决 java.lang.IllegalArgumentException: wrong number of arguments分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13648.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注