1 package Test; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 6 public class PrivateUtil { 7 /** 8 * 利用递归找一个类的指定方法,如果找不到,去父亲里面找直到最上层Object对象为止。 9 * 10 * @param clazz 11 * 目标类 12 * @param methodName 13 * 方法名 14 * @param classes 15 * 方法参数类型数组 16 * @return 方法对象 17 * @throws Exception 18 */ 19 public static Method getMethod(Class clazz, String methodName, 20 final Class[] classes) throws Exception { 21 Method method = null; 22 try { 23 method = clazz.getDeclaredMethod(methodName, classes); 24 } catch (NoSuchMethodException e) { 25 try { 26 method = clazz.getMethod(methodName, classes); 27 } catch (NoSuchMethodException ex) { 28 if (clazz.getSuperclass() == null) { 29 return method; 30 } else { 31 method = getMethod(clazz.getSuperclass(), methodName, 32 classes); 33 } 34 } 35 } 36 return method; 37 } 38 39 /** 40 * 41 * @param obj 42 * 调整方法的对象 43 * @param methodName 44 * 方法名 45 * @param classes 46 * 参数类型数组 47 * @param objects 48 * 参数数组 49 * @return 方法的返回值 50 * @throws Throwable 51 */ 52 public static Object invoke(final Object obj, final String methodName, 53 final Class[] classes, final Object[] objects) throws Throwable { 54 try { 55 Method method = getMethod(obj.getClass(), methodName, classes); 56 method.setAccessible(true);// 调用private方法的关键一句话 57 return method.invoke(obj, objects); 58 } catch (Exception e) { 59 if(e instanceof InvocationTargetException){ 60 Throwable throwable = ((InvocationTargetException) e).getTargetException(); //反射机制通常出现的的错误InvocationTargetException 61 throw throwable; 62 } 63 throw new RuntimeException(e); 64 } 65 } 66 67 public static Object invoke(final Object obj, final String methodName, 68 final Class[] classes) throws Throwable { 69 return invoke(obj, methodName, classes, new Object[] {}); 70 } 71 72 public static Object invoke(final Object obj, final String methodName) throws Throwable { 73 return invoke(obj, methodName, new Class[] {}, new Object[] {}); 74 } 75 76 }
总结:最近在做一个java的动态调用方法,遇到了两个问题:
一:私有方法的访问需要设置: method.setAccessible(true);
二:当java动态调用方法的方法体里有异常抛出,都会被打包成InvocationTargetException异常类并抛出。
因此,在Catch(捕捉异常)的时候进行以下处理:
1 try{ 2 //doXXX 3 }catch (Exception e) { 4 if(e instanceof InvocationTargetException){ 5 Throwable throwable = ((InvocationTargetException) e).getTargetException(); //反射机制通常出现的的错误InvocationTargetException 6 throw throwable; 7 } 8 throw new RuntimeException(e); 9 }