JAVA反射參數傳遞

引用:http://fish2700.blog.163.com/blog/static/130713192009103035723281/java

使用Method反射調用函數時,咱們一般會遇到如下幾種狀況:數組

 public void test(){函數

        System.out.println("函數參數:0");代理

    }blog

    public void test(String str){get

        System.out.println("函數參數:1----------" + str);it

    }io

    public void test(String str1, String str2){編譯

        System.out.println("函數參數:2----------" + str1 +"   " + str2);class

    }

    public void test(Object...objs){

        System.out.print("函數參數:" + objs.length + "----------------");

        for(Object o : objs ){

            System.out.print(o.toString() + "    ");

        }

    }

而當咱們使用Class.getMethod,則須要傳遞所調用函數的參數類型。查看Class.getMethod 的API可知,須要傳遞的類型被表示爲一個可變參數。

咱們知道,傳遞可變參數時,非序列參數會被編譯成編列,即變成一個Object[]類型的數組,可是自己爲序列的則會直接被轉型Object[]數組。

那麼,前三種狀況按照要求傳遞,則傳遞給getMethod的參數會被轉變爲一個一維的參數列表的Object數組。第四種狀況,其函數自己便要求傳遞一個可變參數,即一個Object[]類型的參數。若是咱們按照正常方法傳遞,則此Object[]類型的參數會被直接轉型使用,而咱們最終傳給函數的應該是一個二維的Ojbect數組,即Object[][]類型。getMethod方法的匹配過程是指尋找參數長度與Object數組的長度相等,且每一個參數類型與Object數組每一個數組項相同的方法。

因此,再這種狀況下,咱們應當對每四種狀況下將要傳遞的參數進行一次包裝,將其包裝成一個二維的Object數組。方法以下:

            Object[] obj = new Object[1];

    String[] strs = new String[]{"xiao","she", "qing"};

            obj[0] = strs ;

此時的obj則是咱們將要傳給Class.getMethod的參數,而strs則是咱們要傳遞給調用函數test(Object...objs)的參數。這裏的obj長度爲1是由於可變參數在沒有參數傳遞以前的檢查時的長度爲1,被視爲一元參數。

因爲Spring使用的是Java代理,因此,在Spring中會常常遇到相似的問題。

具體代碼以下:

package test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodDemo {

 public void test(){
  System.out.println("函數參數:0");
 }
 
 public void test(String str){
  System.out.println("函數參數:1----------" + str);
 }
 
 public void test(String str1, String str2){
  System.out.println("函數參數:2----------" + str1 + " " + str2);
 }
 
 public void test(Object...objs){
  System.out.print("函數參數:" + objs.length + "----------------");
  for(Object o : objs ){
   System.out.print(o.toString() + " ");
  }
 }
 /**
  * @param args
  */
 /**
  * @param args
  */
 public static void main(String[] args) {
  
  //testMethod();
  printMethodType();
 }
 
 public static void printMethodType(){
  Method[] methods = MethodDemo.class.getMethods();
  Class[] cs;
  for(Method m : methods){
   System.out.println("----------------" + m.getName() + "----------------");
   cs = m.getParameterTypes();
   System.out.println(cs.length);
   for(Class c : cs){
    System.out.println(c.toString());
   }
  }
 }
 
 public static void testMethod(){
  MethodDemo demo = new MethodDemo();
  Method method;
  try {
   method = MethodDemo.class.getMethod("test", null);
   method.invoke(demo, null);
   System.out.println("--------------------------------------");

   String content = "xiao";
   method = MethodDemo.class.getMethod("test", String.class);
   method.invoke(demo, content);
   System.out.println("--------------------------------------");

   String str1 = "xiao";
   String str2 = "qing";
   method = MethodDemo.class.getMethod("test", String.class, String.class);
   method.invoke(demo, str1, str2);
   System.out.println("--------------------------------------");

   Object[] obj = new Object[1];
   obj[0] = new String[]{"xiao", "she", "qing"};
   //obj[1] = new String[]{"xiao", "qing"};
   method = MethodDemo.class.getMethod("test", Object[].class);
   method.invoke(demo, obj);

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

}

相關文章
相關標籤/搜索