使用数组元素作为参数java实例化对象

时间:2014-09-23 22:51:04

标签: java reflection ioc-container instantiation

我在java中使用反射来制作IoC容器,以自动实例化依赖关系。我已经让它以递归的方式工作,但实例化是笨拙而且不是很直观。

import java.lang.reflect.Constructor;
import java.util.ArrayList;

public class IoC {

    public void register(Object type)
    {

    }

    public Object resolve(String type) throws Exception {

        // Get class
        Class c = Class.forName(type);

        // Get class constructors
        Constructor[] constructors = c.getConstructors();

        if (constructors.length > 1) {
            throw new Exception(type + " has more than one constructor. Can't auto instantiate!");
        }

        // The one constructor
        Constructor constructor = constructors[0];

        // Get constructor parameter types
        Class[] parameters = constructor.getParameterTypes();

        // ArrayList to hold dependencies
        Object[] dependencies = new Object[parameters.length];

        if (parameters.length > 0) {
            // Get dependencies recursively
            for (int i = 0; i < parameters.length; i++) {
                dependencies[i] = resolve( parameters[i].getName() );
            }
        }

        if(dependencies.length > 4)
        {
            throw new Exception("Too many dependencies, consider refactoring!");
        }
        else if(dependencies.length == 1) {
            return constructor.newInstance(dependencies[0]);
        }
        else if(dependencies.length == 2) {
            return constructor.newInstance(dependencies[0], dependencies[1]);
        }
        else if(dependencies.length == 3) {
            return constructor.newInstance(dependencies[0], dependencies[1], dependencies[2]);
        }
        else if(dependencies.length == 4) {
            return constructor.newInstance(dependencies[0], dependencies[1], dependencies[2], dependencies[3]);
        }

        return constructor.newInstance();
    }

}

正如您所看到的,我正在做的是检查依赖项数组的长度,然后传入相应数量的参数。

所以我要问的是,有没有办法在实例化时传入依赖项数组,并且数组元素会自动作为单独的参数传递?

希望有道理:)

2 个答案:

答案 0 :(得分:1)

是。就试一试吧。 Object...Object[]基本相同,只是它允许您将多个对象作为单独的参数传递,而不是自己构造数组。阅读varargs

答案 1 :(得分:1)

newInstance方法定义为采用Object...参数:

public T newInstance(Object... initargs)

当调用newInstance时,Java将允许您传递 参数列表 Object[]数组,在这种情况下,传递数组的元素就好像它们是单独的参数一样。所以简单的调用

constructor.newInstance(dependencies)

会做你想做的事。

(棘手的部分是:由于数组本身就是Object,Java如何知道将其视为Object[]并单独传递元素,或将其视为单个对象,使用一个参数作为数组调用该方法?答案是Java假定第一个。要传递Object[]作为一个参数,可以把它转换为(Object)。这都是在编译时计算出来的。程序不会在运行时检查数组是否有一个元素,元素是Object[]或类似的东西。)

另一个注意事项:您也可以传递其他任何数组,但我的Java编译器会给我一个警告。

String[] strings = new String[4];

constructor.newInstance(strings)

warning: non-varargs call of varargs method with inexact argument type for last parameter;
cast to Object for a varargs call
cast to Object[] for a non-varargs call and to suppress this warning

要消除警告,假设您要分别传递所有四个参数:

constructor.newInstance((Object[])strings)