2012-12-28 16 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:這遠非明確 - 但我描述它的方式是我能理解事物的唯一方式出錯了...... –