【问题标题】:instantiate object with array elements as parameters java用数组元素作为参数实例化对象java
【发布时间】:2014-09-23 22:51:03
【问题描述】:

我正在 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();
    }

}

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

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

希望它有意义:)

【问题讨论】:

    标签: java reflection ioc-container instantiation


    【解决方案1】:

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

    public T newInstance(Object... initargs)
    

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

    constructor.newInstance(dependencies)
    

    会做你想做的。

    (棘手的部分是:由于数组本身就是Object,Java 怎么知道将其视为Object[] 并单独传递元素,或者将其视为单个对象,以便方法是使用 one 参数调用,该参数是一个数组?答案是 Java 假定第一个参数。要将 Object[] 作为 one 参数传递,您可以将其强制转换为 @987654330 @。这都是在编译时计算出来的。程序不会在运行时检查数组是否有一个元素并且该元素是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)
    

    【讨论】:

    • 很好的答案!实际上我曾想过如何将数组作为单个参数传递,而您回答了!
    【解决方案2】:

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

    【讨论】:

    • 看不到我将如何使用它?我没有可变参数编号:)
    • The signatureConstructor.newInstance(Object...),基本上等同于Constructor.newInstance(Object[]),所以你只需要constructor.newInstance(dependencies):该方法需要一个对象数组,这就是你所拥有的:一个数组对象。
    • 啊,我明白了!那太简单了,我什至认为我已经尝试过了!谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多