1. 程式人生 > >Java反射中Method類invoke方法的用法

Java反射中Method類invoke方法的用法

對帶有指定引數的指定物件呼叫由此 Method 物件表示的底層方法。個別引數被自動解包,以便與基本形參相匹配,基本引數和引用引數都隨需服從方法呼叫轉換。

如果底層方法是靜態的,那麼可以忽略指定的 obj 引數。該引數可以為 null。

如果底層方法所需的形引數為 0,則所提供的 args 陣列長度可以為 0 或 null。 

如果底層方法是靜態的,並且尚未初始化宣告此方法的類,則會將其初始化。

如果方法正常完成,則將該方法返回的值返回給呼叫者;如果該值為基本型別,則首先適當地將其包裝在物件中。但是,如果該值的型別為一組基本型別,則陣列元素 被包裝在物件中;換句話說,將返回基本型別的陣列。如果底層方法返回型別為 void,則該呼叫返回 null。

obj - 從中呼叫底層方法的物件(簡單的說就是呼叫誰的方法用誰的物件)args - 用於方法呼叫的引數 

  1. package test922;

  2. public class InvokeObj {

  3. public void show() {

  4. System.out.println("無參show()方法。");

  5. }

  6. public void show (String name) {

  7. System.out.println("show方法:" + name);

  8. }

  9. public String[] arrayShow (String[] arr) {

  10. return arr;

  11. }

  12. public String StringShow (String str) {

  13. return str;

  14. }

  15. public int intShow (int num) {

  16. return num;

  17. }

  18. }

  1. package test922;

  2. import java.lang.reflect.InvocationTargetException;

  3. import java.lang.reflect.Method;

  4. public class MethodInvokeTest {

  5. public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

  6. Class<InvokeObj> clazz = InvokeObj.class;

  7. Method[] methods = clazz.getMethods();

  8. System.out.println("以下輸出InvokeObj類的方法:");

  9. for (Method method : methods) {

  10. System.out.println(method);

  11. }

  12. System.out.println("InvokeObj類的無參show()方法:");

  13. Method method1 = clazz.getMethod("show", null);

  14. //會執行無參show()方法

  15. Object obj = method1.invoke(new InvokeObj(),null);

  16. System.out.println("輸出無參show()方法的返回值:"+obj);

  17. System.out.println("InvokeObj類的show()方法: ");

  18. Method method2 = clazz.getMethod("show", String.class);

  19. Object obj1 = method2.invoke(new InvokeObj(), "hello,world");

  20. System.out.println("輸出有參show()方法: ");

  21. System.out.println("InvokeObj類的arrayShow()方法: ");

  22. Method method3 = clazz.getMethod("arrayShow", String[].class);

  23. String[] strs = new String[]{"hello", "world", "!"};

  24. //陣列型別的引數必須包含在new Object[]{}中,否則會報IllegalArgumentException

  25. String[] strings = (String[]) method3.invoke(new InvokeObj(), new Object[]{strs});

  26. for (String str : strings) {

  27. System.out.println("arrayShow的陣列元素:" + str);

  28. }

  29. System.out.println("InvokeObj類的StringShow()方法: ");

  30. Method method4 = clazz.getMethod("StringShow", String.class);

  31. String string = (String) method4.invoke(new InvokeObj(), "Thinking in java");

  32. System.out.println("StringShow()方法的返回值: " + string);

  33. System.out.println("InvokeObj類的intShow()方法: ");

  34. Method method5 = clazz.getMethod("intShow", int.class);

  35. int num = (int) method5.invoke(new InvokeObj(), 89);

  36. System.out.println("intShow()方法的返回值: " + num);

  37. }

  38. }

  1. 以下輸出InvokeObj類的方法:

  2. public void test922.InvokeObj.show(java.lang.String)

  3. public void test922.InvokeObj.show()

  4. public java.lang.String[] test922.InvokeObj.arrayShow(java.lang.String[])

  5. public java.lang.String test922.InvokeObj.StringShow(java.lang.String)

  6. public int test922.InvokeObj.intShow(int)

  7. public final void java.lang.Object.wait() throws java.lang.InterruptedException

  8. public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException

  9. public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException

  10. public boolean java.lang.Object.equals(java.lang.Object)

  11. public java.lang.String java.lang.Object.toString()

  12. public native int java.lang.Object.hashCode()

  13. public final native java.lang.Class java.lang.Object.getClass()

  14. public final native void java.lang.Object.notify()

  15. public final native void java.lang.Object.notifyAll()

  16. InvokeObj類的無參show()方法:

  17. 無參show()方法。

  18. 輸出無參show()方法的返回值:null

  19. InvokeObj類的show()方法:

  20. show方法:hello,world

  21. 輸出有參show()方法:

  22. InvokeObj類的arrayShow()方法:

  23. arrayShow的陣列元素:hello

  24. arrayShow的陣列元素:world

  25. arrayShow的陣列元素:!

  26. InvokeObj類的StringShow()方法:

  27. StringShow()方法的返回值: Thinking in java

  28. InvokeObj類的intShow()方法:

  29. intShow()方法的返回值: 89

Method getMethod(String name, Class<?>... parameterTypes)  
--返回一個 Method 物件,它反映此 Class 物件所表示的類或介面的指定公共成員方法。  

方法後面接收的就是Class類的物件,而如:String.class、int.class這些位元組碼才是Class類的物件

也可以此種方式:

//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));

}
}