2012-12-28 20 views
3

论点,我有以下接口:呼叫Method.invoke()当阵列

interface Foo { 
    void bar(String a, int b); 
} 

我想要调用Foo.bar(上富的实现)反思。 但是,参数在数组,我不知道它的大小。

以下不起作用:

void gee(Foo someFoo, Method bar, Object[] args) { 
    bar.invoke(someFoo, args); 
} 

即不起作用,因为args是由编译器在一个threated作为单个参数和所述阵列不是“扩展”到VARARG但被包裹(内部)更阵列单个元件,即

@Test 
public void varArgTest() { 
    assertTrue(varArgFoo(new Object[] {1, 2}) == 1); 
} 

private static <T> int varArgFoo(T... arg) { 
    return arg.length; 
} 

我怎样才能调用Method.invoke()在这种情况下,使得所述阵列被threated作为可变参数?
或更常见的问题:如何在参数在数组中时调用vararg方法,直到运行时才知道数组的大小。

+0

你的问题不能再被删除,太多的SO用户发布了答案,否则就会把注意力集中在它上面。你可以举办一个主持人,但是你需要拿出一个*真正*的理由让他们为你删除它。 –

+0

@Hans Passant我做过标记,但没有任何版主回复。我改变了标题以避免出现在搜索结果中,因为这个问题有误导性,即使是最多的投票答案是错误的和误导 –

回答

3

下不起作用:

是它。

即不起作用,因为ARGS是由编译器threated作为 单个参数,所述阵列不是“展开”,以可变参数,但是 在一个以上的阵列与单个元件包裹(内部),即

随着你提出的代码,数组的元素应该成为可变参数参数。如果这不会发生在你身上,或者你没有显示你的实际代码,或者其他的错误。

如果不知何故args变量没有数组类型(例如键入Object),那么可能会发生这种情况。但是,这不是你展示的代码。

或者,如果你有没有显示(例如,你正在尝试做一些像bar.invoke(someFoo, firstArg, args);一些“额外”的论点,那么就不会扩大args,因为你正在使用的方法的可变参数的形式了。

+0

你说得对,在我的测试用例中,我错误地使用了'assertFalse'而不是'assertTrue'。但我不能删除这个问题。我将其标记,以便主持人将其删除,但尚未发生。 –

10

可变参数实际上是一个带有一些额外元数据的数组参数。所以,当你使用Method.invoke,你需要用数组中另一数组:

Object[] varargs = new Object[] { 10, 20 }; 
Object argumentArray = new Object[] { varargs }; 
method.invoke(target, argumentArray); 
+0

从问题来看,OP听起来像他们有相反的问题,即他们希望它不被包裹,但它被包裹 – newacct

+0

@newacct:这远非明确 - 但我描述它的方式是我能理解事物的唯一方式出错了...... –