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 }
