Java反射中Method類invoke方法的用法
對帶有指定引數的指定物件呼叫由此 Method
物件表示的底層方法。個別引數被自動解包,以便與基本形參相匹配,基本引數和引用引數都隨需服從方法呼叫轉換。
如果底層方法是靜態的,那麼可以忽略指定的 obj
引數。該引數可以為 null。
如果底層方法所需的形引數為 0,則所提供的 args
陣列長度可以為 0 或 null。
如果底層方法是靜態的,並且尚未初始化宣告此方法的類,則會將其初始化。
如果方法正常完成,則將該方法返回的值返回給呼叫者;如果該值為基本型別,則首先適當地將其包裝在物件中。但是,如果該值的型別為一組基本型別,則陣列元素不 被包裝在物件中;換句話說,將返回基本型別的陣列。如果底層方法返回型別為 void,則該呼叫返回 null。
obj
- 從中呼叫底層方法的物件(簡單的說就是呼叫誰的方法用誰的物件)args
- 用於方法呼叫的引數
-
package test922;
-
public class InvokeObj {
-
public void show() {
-
System.out.println("無參show()方法。");
-
}
-
public void show (String name) {
-
System.out.println("show方法:" + name);
-
}
-
public String[] arrayShow (String[] arr) {
-
return arr;
-
}
-
public String StringShow (String str) {
-
return str;
-
}
-
public int intShow (int num) {
-
return num;
-
}
-
}
-
package test922;
-
import java.lang.reflect.InvocationTargetException;
-
import java.lang.reflect.Method;
-
public class MethodInvokeTest {
-
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
-
Class<InvokeObj> clazz = InvokeObj.class;
-
Method[] methods = clazz.getMethods();
-
System.out.println("以下輸出InvokeObj類的方法:");
-
for (Method method : methods) {
-
System.out.println(method);
-
}
-
System.out.println("InvokeObj類的無參show()方法:");
-
Method method1 = clazz.getMethod("show", null);
-
//會執行無參show()方法
-
Object obj = method1.invoke(new InvokeObj(),null);
-
System.out.println("輸出無參show()方法的返回值:"+obj);
-
System.out.println("InvokeObj類的show()方法: ");
-
Method method2 = clazz.getMethod("show", String.class);
-
Object obj1 = method2.invoke(new InvokeObj(), "hello,world");
-
System.out.println("輸出有參show()方法: ");
-
System.out.println("InvokeObj類的arrayShow()方法: ");
-
Method method3 = clazz.getMethod("arrayShow", String[].class);
-
String[] strs = new String[]{"hello", "world", "!"};
-
//陣列型別的引數必須包含在new Object[]{}中,否則會報IllegalArgumentException
-
String[] strings = (String[]) method3.invoke(new InvokeObj(), new Object[]{strs});
-
for (String str : strings) {
-
System.out.println("arrayShow的陣列元素:" + str);
-
}
-
System.out.println("InvokeObj類的StringShow()方法: ");
-
Method method4 = clazz.getMethod("StringShow", String.class);
-
String string = (String) method4.invoke(new InvokeObj(), "Thinking in java");
-
System.out.println("StringShow()方法的返回值: " + string);
-
System.out.println("InvokeObj類的intShow()方法: ");
-
Method method5 = clazz.getMethod("intShow", int.class);
-
int num = (int) method5.invoke(new InvokeObj(), 89);
-
System.out.println("intShow()方法的返回值: " + num);
-
}
-
}
-
以下輸出InvokeObj類的方法:
-
public void test922.InvokeObj.show(java.lang.String)
-
public void test922.InvokeObj.show()
-
public java.lang.String[] test922.InvokeObj.arrayShow(java.lang.String[])
-
public java.lang.String test922.InvokeObj.StringShow(java.lang.String)
-
public int test922.InvokeObj.intShow(int)
-
public final void java.lang.Object.wait() throws java.lang.InterruptedException
-
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
-
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
-
public boolean java.lang.Object.equals(java.lang.Object)
-
public java.lang.String java.lang.Object.toString()
-
public native int java.lang.Object.hashCode()
-
public final native java.lang.Class java.lang.Object.getClass()
-
public final native void java.lang.Object.notify()
-
public final native void java.lang.Object.notifyAll()
-
InvokeObj類的無參show()方法:
-
無參show()方法。
-
輸出無參show()方法的返回值:null
-
InvokeObj類的show()方法:
-
show方法:hello,world
-
輸出有參show()方法:
-
InvokeObj類的arrayShow()方法:
-
arrayShow的陣列元素:hello
-
arrayShow的陣列元素:world
-
arrayShow的陣列元素:!
-
InvokeObj類的StringShow()方法:
-
StringShow()方法的返回值: Thinking in java
-
InvokeObj類的intShow()方法:
-
intShow()方法的返回值: 89
Method getMethod(String name, Class<?>... parameterTypes) |
也可以此種方式:
//getMethod第一個引數是方法名,第二個引數是該方法的引數型別,
//因為存在同方法名不同引數這種情況,所以只有同時指定方法名和引數型別才能唯一確定一個方法
Method method = XXX.getClass().getMethod(methodName,new Class[0]);
//第一個引數是具體呼叫該方法的物件
//第二個引數是執行該方法的具體引數
如一個函式 int Test(int a, String str);
對應的getMethod方法:
1. getMethod("Test",int.class,String.class);
2. getMethod("Test",new Class[]{int.class,String.class});
然後通過invoke來呼叫此方法:
函式原型:Object Java.lang.reflect.Method.invoke(Object receiver, Object... args)
//Method類的invoke(Object obj,Object args[])方法接收的引數必須為物件,
//如果引數為基本型別資料,必須轉換為相應的包裝型別的物件。invoke()方法的返回值總是物件,
//如果實際被呼叫的方法的返回型別是基本型別資料,那麼invoke()方法會把它轉換為相應的包裝型別的物件,再將其返回
receiver:該方法所在類的一個物件
args: 傳入的引數 如 100,“hello”
詳細參見:http://www.linuxidc.com/Linux/2009-09/21571.htm
import java.lang.reflect.Method;
public class InvokeTester {
public int add(int param1, int param2) {
return param1 + param2;
}
public String echo(String mesg) {
return "echo" + mesg;
}
public static void main(String[] args) throws Exception {
Class classType = InvokeTester.class;
Object invokertester = classType.newInstance();
Method addMethod = classType.getMethod("add", new Class[] { int.class,
int.class });
//Method類的invoke(Object obj,Object args[])方法接收的引數必須為物件,
//如果引數為基本型別資料,必須轉換為相應的包裝型別的物件。invoke()方法的返回值總是物件,
//如果實際被呼叫的方法的返回型別是基本型別資料,那麼invoke()方法會把它轉換為相應的包裝型別的物件,
//再將其返回
Object result = addMethod.invoke(invokertester, new Object[] {
new Integer(100), new Integer(200) });
//在jdk5.0中有了裝箱 拆箱機制 new Integer(100)可以用100來代替,系統會自動在int 和integer之間轉換
System.out.println(result);
Method echoMethod = classType.getMethod("echo",
new Class[] { String.class });
result = echoMethod.invoke(invokertester, new Object[] { "hello" });
System.out.println(result);
}
}
public class Test {
public static void main(String[] args) throws Exception {
String field = "UserName";
String methodName = "";
World world = new World();
Class xom = world.getClass();
methodName = "set"+field;
Method method = xom.getMethod(methodName, String.class);
Object[] obj = new Object[1];
obj[0] = "guolei";
method.invoke(world, obj);
// System.out.println(world.getUserName());
methodName = "get"+field;
Method method2 = xom.getMethod(methodName);
System.out.println(method2.invoke(world));
}
}