通過Java發射機制調用可變參數函數


1、獲取可變參數的函數
      獲取可變參數的函數與獲取參數類型為數組類型一樣。   clazz.getMethod("test", Object[].class) ;
   其中Object為可變參數或者數組的數據類型
   例如:
   public void test(String ... params){
      ...
   }
   則獲取該可變參數的函數如下:
       Class  clazz = Class.forName("com.demo003.MainThread");

   Method method = clazz.getMethod("test", String[].class);

 
 
2、執行調用帶有可變參數的函數
      此時,我們應該如何將多個參數值傳給可變參數呢?
     method.invoke(obj , new String[]{"a" ,"b" ,"C"}) ,
     或者是
     method.invoke(mainThread,  "a"  , "b"  , "c"  );
     這樣調用對嗎?
     以上兩種方式的調用會報: Exception in thread "main"  java.lang.IllegalArgumentException : wrong number of arguments
      是不是感覺挺奇怪的?
     其實Method的invoke方法的參數也是一個可變參數,如下是invoke的定義
     
     那么當參數 new String[]{"a" ,"b" ,"C"})傳給invoke方法時,會自動拆分成3個參數:"a" ,"b" ,"c" , 那么invoke方法自然認為目標調用函數是帶有3個形參的,
     所以invoke方法調用目標函數時,會將這3個參數傳遞給目標函數,而目標函數僅僅是一個可變參數而已,所以就發生參數個數不一致的問題。對於反射來說,
     是通過將數組類型對象傳遞給目標函數的可變參數的, 即它只需要將多個參數組成一個數組,然后將這個數組傳遞給可變參數 ,然后目標函數的可變參數再自動將這個數組值自動拆分成多個參數值。
     
     那么我們應該如何傳呢?
     既然 知道了如果數組類型與invoke函數的參數類型(為Object)可以轉換,並且為一維數組時,它會自動拆分成多個參數,導致最終參數個數不一致而出現異常。
     同時 知道了反射 是通過將數組對象傳遞給目標函數的可變參數的。那么也就以意味這個,可以將這個需要傳遞數組類型對象轉換invoke方法不可轉換拆分的對象即可。
     解決方案如下:
    1)將數據類型對象強制轉換成一個Object類型對象,這樣就不會進行自動拆分了
      method.invoke((Object)   new String[]{"a" ,"b" ,"C"}) 
 
    2)將當前數組再包裝成一個一維數組,從而達到拆分出來的是一個數組對象
     Object[]p = new Object[]{  new String[]{"a" ,"b" ,"C"}  }
      method.invoke(p)
 
    可能還有其他的解決方案,只要最終達到invoke不能拆分該數組參數,或者是拆分后也只有該數組對象這個參數即可
 



 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM