反射构造器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);

错误

分析:这里虽然获取了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);

结果

虽然构造成功了,但我们怎么就知道了传入参数却是(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);

构造成功

结果证明猜想是正确的。

# java 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×