Java反射學習簡單應用

這個應用的目的是,傳入類名,傳入方法名,傳入調用的參數便可以調用制定類下的制定方法。java

這個應用的好處是,類名和方法名從配置文件中讀入,能夠改變。相似於一個小型的類加載,而後實例化,而後調用。因此,這個例子對理解JDK加載類也有點點好處。ide

這個應用中包含三個類。測試

Calculator:這個類是對計算器的簡單建模。用來做測試的。spa

MethodInvoker:這個類有兩個方法,是核心。weakInvoke和Invoke。關於這兩個方法的解釋在代碼註釋中。blog

InvokerTest:測試驅動。get

Calculator.javastring

  
  
  
  
  1. public class Calculator {  
  2.      
  3.    public int add(int a,int b){  
  4.        return a+b;  
  5.    }  
  6.      
  7.    public int sub(int a,int b){  
  8.        return a-b;  
  9.    }  
  10.      
  11.    public int multify(int a,int b){  
  12.        return a*b;  
  13.    }  
  14.      
  15.    public int div(int a,int b){  
  16.        if(b!=0)  
  17.            return a/b;  
  18.        return 0;  
  19.    }  
  20.      
  21.    public int add(int a,int b,int c)  
  22.    {  
  23.        return a+b+c;  
  24.    }  

MethodInvoker.javait

  
  
  
  
  1. public class MethodInvoker {  
  2.      
  3.     /**  
  4.      * 傳入類名便可調用,可是不支持含有簡單類型的方法,由於簡單類型回自動打包  
  5.      * @param className 要調用的類  
  6.      * @param methodName 要調用的方法  
  7.      * @param params 調用的參數
  8. * @return  調用後的結果 
  9.      */ 
  10.     public static Object weakInvoke(String className,String methodName,Object[] obj)  
  11.     {  
  12.           
  13.         try {  
  14.             Class c = Class.forName(className);  
  15.             Class[] paraClasses=new Class[obj.length];  
  16.             for(int i=0;i<obj.length;i++)  
  17.             {  
  18.                 paraClasses[i]=obj[i].getClass();  
  19.             }  
  20.             try {  
  21.                 Method m=c.getMethod(methodName, paraClasses);  
  22.                 Object instance=c.newInstance();  
  23.                 return m.invoke(instance, obj);  
  24.             } catch (SecurityException e) {  
  25.                 e.printStackTrace();  
  26.             } catch (NoSuchMethodException e) {  
  27.                 e.printStackTrace();  
  28.             } catch (IllegalArgumentException e) {  
  29.                 e.printStackTrace();  
  30.             } catch (IllegalAccessException e) {  
  31.                 e.printStackTrace();  
  32.             } catch (InvocationTargetException e) {  
  33.                 e.printStackTrace();  
  34.             } catch (InstantiationException e) {  
  35.                 e.printStackTrace();  
  36.             }  
  37.         } catch (ClassNotFoundException e1) {  
  38.             e1.printStackTrace();  
  39.         }  
  40.         return null;  
  41.     }  
  42.     /**  
  43.      * 動態方法調用  
  44.      * @param className 要調用的類  
  45.      * @param methodName 要調用的方法  
  46.      * @param params 調用的參數  
  47.      * @return  調用後的結果  
  48.      */ 
  49.     public static Object invoke(String className,String methodName,Object[] params)  
  50.     {  
  51.             Object returnObj=null;  
  52.                 try {  
  53.                     Class c= Class.forName(className);  
  54.                     Method[] ms=c.getMethods();  
  55.                     Object obj=c.newInstance();  
  56.                     for(int i=0;i<ms.length;i++)  
  57.                     {  
  58.                         Method m=ms[i];  
  59.                         if(m.getName().endsWith(methodName))  
  60.                         {  
  61.                             try {  
  62.                                 returnObj=m.invoke(obj, params);  
  63.                             } catch (IllegalArgumentException e) {//參數錯誤  
  64.                                 returnObj=null;  
  65.                                 continue;  
  66.                             } catch (InvocationTargetException e) {  
  67.                                 e.printStackTrace();  
  68.                                 break;  
  69.                             }  
  70.                             break;  
  71.                         }  
  72.                     }  
  73.                 } catch (ClassNotFoundException e) {  
  74.                     e.printStackTrace();  
  75.                 } catch (InstantiationException e) {  
  76.                     e.printStackTrace();  
  77.                 } catch (IllegalAccessException e) {  
  78.                     e.printStackTrace();  
  79.                 }  
  80.          return returnObj;  
  81.                   
  82.     }  
  83. }  

InvokerTest.javaio

  
  
  
  
  1. public class InvokerTest {  
  2.   public static void main(String[] args) {  
  3.       
  4.       try {  
  5.         PropertyReader reader=new PropertyReader("invoke.properties");  
  6.         String name=reader.getProperty("class");  
  7.         String method=reader.getProperty("method");  
  8.         Object[] params=new Object[]{1,2};  
  9.         System.out.println(MethodInvoker.invoke(name, method,params));  
  10.     } catch (SecurityException e) {  
  11.         e.printStackTrace();  
  12.     } catch (IllegalArgumentException e) {  
  13.         e.printStackTrace();  
  14.   }  
  15.   }  

invoke.properties直接放在工程根路徑下,invoke.properties中的內容。class

  
  
  
  
  1. class=neu.swc.tzy.methods.Calculator  
  2. method=add 

執行結果:3.

若是把InvokeTest中的Object[] params=new Object[]{1,2};改成Object[] params=new Object[]{1,2,3};則能夠正確地返回結果6.也就是說,該應用支持重載的方法調用。

若是把配置文件中的method改成sub便可以變爲減法。

屬性配置文件讀取的方法見:http://snowteng17.blog.51cto.com/1532294/330459

相關文章
相關標籤/搜索