使用代理实现对私有方法的访问

来源:互联网 发布:淘宝达人在哪里 编辑:程序博客网 时间:2024/05/17 20:25

    public static Object invokePrivateMethod(Object obj, String methodName,
            Class[] types, Object[] args) throws Exception {
        Object ret = null;
        try {
            // getMethod() は public のみが対象となるため getDeclaredMethod() を使用します。
            Method callee = obj.getClass().getDeclaredMethod(methodName, types);

            // Accessible フラグを true とすることで、private, package,
            // protected でもアクセスできるようになります。
            callee.setAccessible(true);
            
            // 実際にメソッドを呼び出します。
            ret = callee.invoke(obj, args);
        }
        // メソッド内の例外は InvocationTargetException にラップされて送付されます。
        catch (InvocationTargetException e) {
            if (e.getTargetException() instanceof Exception) {
                throw (Exception) e.getTargetException();
            }
            System.err.println(e.getTargetException().getMessage());
            throw e;
        }
        // それ以外の例外が発生したときは、今回はそのまま例外をスローすることにしています。
        // テスト時はコンソールに例外が出力されるので、それを参考にして下さい。
        catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return ret;
    }

         调用:第一个参数类对象,第二个参数方法名,点三个参数方法参数类型及个数,第四个参数参数值

  invokePrivateMethod(logic, "checkTelegramParam", new Class[] { String.class, String.class, String.class, String.class }, new Object[] { shirei, destGwNo, procDate, procTime });

注意第一个参数一定是类的实例,不然出错。

第二种方法将以上方法详细化了:

public static Object invokeMethod(final Object object, final String methodName, final Class<?>[] parameterTypes,
    final Object[] parameters) throws Exception {
   Method method = getDeclaredMethod(object, methodName, parameterTypes);
   if (method == null) {
    throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
   }

   method.setAccessible(true);

   try {
    return method.invoke(object, parameters);
   } catch (Exception e) {
    throw e;
   }
  } 
  /**
   *
   */
  protected static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes) {

   for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
     .getSuperclass()) {
    try {
     return superClass.getDeclaredMethod(methodName, parameterTypes);
    } catch (NoSuchMethodException e) {//NOSONAR
     // Field is not in this class,get super class
    }
   }
   return null;
  } 

第二种方法与第一种方法是一个意思。