使用HashMap和反射来调用具有可变参数类型的方法

时间:2014-08-10 08:09:12

标签: java reflection types variadic-functions

所以,我有以下情况:

  • 我有一个名为AIInstruction的类,实际上并不是要自己实例化,而是通过子类。

  • 我有一大堆名为AIInstruction_***的类,它们扩展了AIInstruction。这些类中的每一个都有一个构造函数,但它们所需的参数类型和数量不同。

  • 我有一个看起来像这样的经理类:

    public class AIControls
    {
        public static HashMap<String, Class<? extends AIInstruction>> INSTRUCTION_DICTIONARY = new HashMap<String, Class<? extends AIInstruction>>();
        static {
            INSTRUCTION_DICTIONARY.put("rotateTowards", AIInstruction_rotateTowards.class);
            INSTRUCTION_DICTIONARY.put("moveToPoint", AIInstruction_moveToPoint.class);
            // (etc...)
        }
    
        LinkedList<AIInstruction> _instruction_queue;
    
        public AIControls()
        {
            _instruction_queue = new LinkedList<AIInstruction>();
        }
    
        public void addInstruction(String instruction, Object... params)
        {
            /*
            ???
            */
        }
    }
    

我想在addInstruction内做的是创建一个类的实例,其INSTRUCTION_DICTIONARY内的键是instruction,并将此新实例添加到_instruction_queue LinkedList的。 params varargs是instruction所需的类构造函数方法所需的参数。

从我的研究中,我发现反射几乎是要走的路。我之前从未使用过反射,所以我想我可能会错过一两件事。这是我走了多远:

public void addInstruction(String instruction, Object... params)
{
    Class<?> the_class = INSTRUCTION_DICTIONARY.get(instruction);
    Constructor<?> the_constructor = the_class.getConstructor(/* ??? */);
    AIInstruction new_instruction = the_constructor.newInstance(params);

    _instruction_queue.add(new_instruction);
}

但是,该代码基本上存在两个问题:

  1. 我不确定应该代替/* ??? */。我想我应该把参数的类型放在一起,但它们可以是任何东西,因为每个AIInstruction子类都有非常不同的构造函数(类型和参数数量)。

  2. 我不确定newInstance调用是否有效,因为params数组包含Object类型的实例。

  3. 非常感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用Class.getConstructors()来获取类中所有构造函数的数组。假设您只有一个构造函数,您只需检查大小以防止OOB异常,并将[0]保存为构造函数。

看起来你不需要知道构造函数采用什么类型的参数,但是如果你这样做,你总是可以使用Constructor.getParameterTypes()。如前所述,如果情况确实如此,这也可用于识别多个构造函数。