2017-08-28 16 views
0

我正面臨一個問題,我需要使用反射調用來調用帶有參數String,String,String ...的方法。我的代碼如下如何對一個方法執行反射調用後攜帶String,String,String ...作爲參數?

public void testArrayParams(String first, String second, String... strings) { 

    System.out.println("First: " + first); 
    System.out.println("Second: " + second); 

    System.out.println("Size of String... strings: " + strings.length); 
    for(int i = 0; i < strings.length; i ++) { 
     System.out.println(i + ": " + strings[i]); 
    } 

} 

及以下的主要方法

public static void main(String[] args) { 
    Dummy dummy = new Dummy(); 
    //dummy.testArrayParams("Hello", "World", "This is ", "passed in ", "format String... strings."); 

    String[] params = {"Hello", "World", "This is ", "passed in ", "format String... strings."}; 
    String method = "testArrayParams"; 

    try { 
     Class<?> clazz = Class.forName("com.bt.testafix.utils.Dummy"); 
     Method[] methods = clazz.getMethods(); 

     for (Method m : methods) { 
      if (m.getName().equalsIgnoreCase(method)) { 
       //m.invoke(clazz, (Object[]) params); 
       m.invoke(clazz, new Object[]{params}); 
       break; 
      } 
     } 

    } catch (ClassNotFoundException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

它拋出異常下面當我運行的代碼

java.lang.IllegalArgumentException: object is not an instance of declaring class 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 

我試圖m.invoke(clazz, (Object[]) params);變化,這是一個鑄件,但仍然給出相同的例外。任何想法我可以解決這個問題?

+0

將代碼從'm.invoke(clazz,new Object [] {params});'改爲'm.invoke(dummy,params);' 第一個參數守ld是你希望調用該方法的類的實例。 – Gautam

回答

2

如果您查看Method實例爲您提供的參數信息,則會發現最後一個參數是String[]參數,因爲可變參數在Java中是作爲數組參數實現的。

所以,你應該params反映:

Object[] params = { 
    "Hello", 
    "World", 
    new String[] { 
     "This is ", 
     "passed in ", 
     "format String... strings." 
    } 
}; 

另外,兩個問題您invoke電話:

  1. 的方法是不clazz的方法,你需要一個實例(因爲它是一種實例方法)。例如,clazz.newInstance()或類似的。

  2. 您已經使用了new Object[]{params},這意味着您要將一個單個參數傳遞給該方法。它預計有三個。

所以:

m.invoke(clazz.newInstance(), params); 

Working live copy

+0

謝謝你,你解決了我的問題。現在工作正常。 – chris

+0

但我在這裏有一個問題。我嘗試運行這一行代碼 - dummy.testArrayParams(「你好」,「世界」,「這是」,「傳入」,「格式字符串...字符串。它工作正常。我不需要像你提到的那樣顯式地聲明String數組。這是爲什麼? – chris

+0

@chris:當你明確地使用方法時,編譯器爲你處理可變參數。但是當你使用反射時,你必須自己處理可變參數(通過爲可變參數參數提供數組)。 –

0

對於靜態方法,調用的第一個參數爲空,對於非靜態方法,它應該是聲明類的一個實例( )

相關問題