这个应用的目的是,传入类名,传入方法名,传入调用的参数即可以调用制定类下的制定方法。

这个应用的好处是,类名和方法名从配置文件中读入,可以改变。类似于一个小型的类加载,然后实例化,然后调用。所以,这个例子对理解JDK加载类也有点点好处。

这个应用中包含三个类。

Calculator:这个类是对计算器的简单建模。用来作测试的。

MethodInvoker:这个类有两个方法,是核心。weakInvoke和Invoke。关于这两个方法的解释在代码注释中。

InvokerTest:测试驱动。

Calculator.java

   
   
   
   
  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.java

   
   
   
   
  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
  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
  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.java

   
   
   
   
  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中的内容。

   
   
   
   
  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