反射构造器wrong number of arguments错误

记一次在获取构造器时报出wrong number of arguments错误,在通过反射来使用数组或可变参数构造器时,反射出来的构造方法里使用的参数是数组类型。这时不能直接使用类型数组去入参给newInstance。我们看一下newInstance的代码


public T newInstance(Object ... initargs)
        throws InstantiationException, IllegalAccessException,
        IllegalArgumentException, InvocationTargetException
{
    if (!override) {
        if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
            Class<?> caller = Reflection.getCallerClass();
            checkAccess(caller, clazz, null, modifiers);
        }
    }
    if ((clazz.getModifiers() & Modifier.ENUM) != 0)
        throw new IllegalArgumentException("Cannot reflectively create enum objects");
    ConstructorAccessor ca = constructorAccessor;   // read volatile
    if (ca == null) {
        ca = acquireConstructorAccessor();
    }
    @SuppressWarnings("unchecked")
    T inst = (T) ca.newInstance(initargs);
    return inst;
}

看到方法是使用Object的可变参数数组,如果使用具体类型数组去构造这个对象,newInstance方法会将使用构造具体类型的具体数量的构造器去构造这个对象。

举例:这是类C的一个构造器,需要使用B数组。

public C(B... bs){
    for(B b:bs){
        System.out.println(b.getName());
    }
    System.out.println("构造C");
}

使用反射构造报出错误。

B[] bs = new B[] {new B("name1",18,"des1"),new B("name2",20,"des2")};
Constructor constructor = C.class.getDeclaredConstructor(B[].class);
C c1 = (C)constructor.newInstance(bs);
14899865-14aeb83cda0782a7.png
错误

分析:这里虽然获取了B[]为参数的构造器,但是传入参数却是(B.class,B.class),所以运行的时候,就报出了错误的参数数量。所以在newInstance时,应该用Object数组将B[]转为Object。

正确写法:


B[] bs = new B[] {new B("name1",18,"des1"),new B("name2",20,"des2")};
Object parameters[]=new Object[] {bs};
Constructor constructor = C.class.getDeclaredConstructor(B[].class);
C c = (C)constructor.newInstance(parameters);

14899865-6045529a1c92739f.png
结果

虽然构造成功了,但我们怎么就知道了传入参数却是(B.class,B.class),我们再来看看,我们分析的对不对。

再创建一个构造方法

public C(B b1,B b2){
    System.out.println("非可变构造器");
}

在启动方法中添加使用这个构造方法的反射构造器

Constructor constructor1 = 
        C.class.getDeclaredConstructor(B.class,B.class);
C c1 = (C)constructor1.newInstance(bs);
14899865-6fb112bdd83107b7.png
构造成功

结果证明猜想是正确的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值