这个应用的目的是,传入类名,传入方法名,传入调用的参数即可以调用制定类下的制定方法。
这个应用的好处是,类名和方法名从配置文件中读入,可以改变。类似于一个小型的类加载,然后实例化,然后调用。所以,这个例子对理解JDK加载类也有点点好处。
这个应用中包含三个类。
Calculator:这个类是对计算器的简单建模。用来作测试的。
MethodInvoker:这个类有两个方法,是核心。weakInvoke和Invoke。关于这两个方法的解释在代码注释中。
InvokerTest:测试驱动。
Calculator.java
- public class Calculator {
- public int add(int a,int b){
- return a+b;
- }
- public int sub(int a,int b){
- return a-b;
- }
- public int multify(int a,int b){
- return a*b;
- }
- public int div(int a,int b){
- if(b!=0)
- return a/b;
- return 0;
- }
- public int add(int a,int b,int c)
- {
- return a+b+c;
- }
- }
MethodInvoker.java
- public class MethodInvoker {
- /**
- * 传入类名即可调用,但是不支持含有简单类型的方法,因为简单类型回自动打包
- * @param className 要调用的类
- * @param methodName 要调用的方法
- * @param params 调用的参数
- * @return 调用后的结果
- */
- public static Object weakInvoke(String className,String methodName,Object[] obj)
- {
- try {
- Class c = Class.forName(className);
- Class[] paraClasses=new Class[obj.length];
- for(int i=0;i<obj.length;i++)
- {
- paraClasses[i]=obj[i].getClass();
- }
- try {
- Method m=c.getMethod(methodName, paraClasses);
- Object instance=c.newInstance();
- return m.invoke(instance, obj);
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- }
- } catch (ClassNotFoundException e1) {
- e1.printStackTrace();
- }
- return null;
- }
- /**
- * 动态方法调用
- * @param className 要调用的类
- * @param methodName 要调用的方法
- * @param params 调用的参数
- * @return 调用后的结果
- */
- public static Object invoke(String className,String methodName,Object[] params)
- {
- Object returnObj=null;
- try {
- Class c= Class.forName(className);
- Method[] ms=c.getMethods();
- Object obj=c.newInstance();
- for(int i=0;i<ms.length;i++)
- {
- Method m=ms[i];
- if(m.getName().endsWith(methodName))
- {
- try {
- returnObj=m.invoke(obj, params);
- } catch (IllegalArgumentException e) {//参数错误
- returnObj=null;
- continue;
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- break;
- }
- break;
- }
- }
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- return returnObj;
- }
- }
InvokerTest.java
- public class InvokerTest {
- public static void main(String[] args) {
- try {
- PropertyReader reader=new PropertyReader("invoke.properties");
- String name=reader.getProperty("class");
- String method=reader.getProperty("method");
- Object[] params=new Object[]{1,2};
- System.out.println(MethodInvoker.invoke(name, method,params));
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
- }
invoke.properties直接放在工程根路径下,invoke.properties中的内容。
- class=neu.swc.tzy.methods.Calculator
- 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