2009-11-23 16 views
16

我對Java很新,而且面臨反射問題。用Java反射如何實例化一個新對象,然後調用它的方法?

比方說,我必須動態地調用該方法fooMethod的類Foobar

我得到了Foobar至今實例的實例:

Object instance = Class.forName("Foobar").newInstance(); 

比方說,我知道有一個方法fooMethod在這個對象上(我甚至可以用Class.forName("Foobar").getDeclaredMethods()來檢查這個),請問怎麼調用它?

回答

2

這應該爲你工作:

((Foobar)instance).fooMethod() 
+1

檢查所有的方法,你只能這樣做,如果你知道在編譯時,該實例將是一個FooBar的 - 這那麼意味着你不需要首先使用反射! – Chii

+2

@Chii:不是必需的。 FooBar可以是最常用的類型,從反射中獲得的類型是繼承的。這就是例如JDBC驅動程序的工作方式以及設計了多少插件體系結構。 – quosoo

6
Method method = getClass().getDeclaredMethod("methodName"); 
m.invoke(obj); 

這是在情況下該方法沒有參數。如果有,則將參數類型作爲參數附加到此方法。 obj是您正在調用該方法的對象。

See the java.lang.Class docs

+0

什麼是getClass? –

3

您可以通過閱讀它here開始。

至於你的代碼是後就是這個樣子(來自同一個資源):

Method[] allMethods = c.getDeclaredMethods(); 
    for (Method m : allMethods) { 
    String mname = m.getName(); 
    if (!mname.startsWith("test") 
     || (m.getGenericReturnType() != boolean.class)) { 
     continue; 
    } 
    Type[] pType = m.getGenericParameterTypes(); 
    if ((pType.length != 1) 
     || Locale.class.isAssignableFrom(pType[0].getClass())) { 
     continue; 
    } 

    out.format("invoking %s()%n", mname); 
    try { 
     m.setAccessible(true); 
     Object o = m.invoke(t, new Locale(args[1], args[2], args[3])); 
     out.format("%s() returned %b%n", mname, (Boolean) o); 

    // Handle any exceptions thrown by method to be invoked. 
    } catch (InvocationTargetException x) { 
     Throwable cause = x.getCause(); 
     err.format("invocation of %s failed: %s%n", 
       mname, cause.getMessage()); 
    } 
4

純粹反映:Method.invoke。 另一種解決方案是要求您反射性地創建的項目實現一個已知的接口並轉換到該接口並正常使用。

後者通常用於「插件」,前者不常用。

2

您可以使用反射

樣品類

package com.google.util; 
Class Maths 
{ 

public Integer doubleIt(Integer a) 
{ 
return a*2; 
} 
} 

,並使用類似這個 -

步驟1: - 負載類具有給定輸入的字符串類型

Class<?> obj=Class.forName("Complete_ClassName_including_package"); 

//like:- Class obj=Class.forName("com.google.util.Maths"); 

第2步: - GET方法與給定的名稱和參數類型

Method method=obj.getMethod("NameOfMthodToInvoke", arguments); 

//arguments need to be like- java.lang.Integer.class 
//like:- Method method=obj.getMethod("doubleIt",java.lang.Integer.class); 

第3步: - Invoke方法通過傳遞對象和論據的實例

Object obj2= method.invoke(obj.newInstance(), id); 
//like :- method.invoke(obj.newInstance(), 45); 

YOU CAN DO第2步也這樣

(當你不知道具體的方法在一個類中存在你通過循環法的陣列)

Method[] methods=obj.getMethods(); 

Method method=null; 

for(int i=0;i&lt;methods.length();i++) 

{ 

if(method[1].getName().equals("methodNameWeAreExpecting")) 

{ 

method=method[i]; 

} 

} 
相關問題