反射调用父类方法


/**
* 类 描 述 :

* 修改备注:
* 创建时间:Aug 22, 2014 11:37:31 AM
*  今天和一位朋友谈到父类私有方法的调用问题,本来以为利用反射很轻松就可以实现
*  因为在反射看来根本不区分是否是private的,没有想到调用本 身的私有方法是可以的,
*  但是调用父类的私有方法则不行,后来纠其原因很有可能是因为getDeclaredMethod方法和getMethod方法并不
*  会查找父类的私有方法,于是只好自己写递归了,经过尝试果然如此。把代码放出来方便更多人。
*  这段代码可以解决很多实际问题,不过利用反射来做的话性能不会 太好。
*/
public class PrivateUtil {
/**
* 利用递归找一个类的指定方法,如果找不到,去父亲里面找直到最上层Object对象为止。
     * @param clazz
     *            目标类
     * @param methodName
     *            方法名
     * @param classes
     *            方法参数类型数组
     * @return 方法对象
     * @throws Exception
*/ 
  public static Method getMethod(Class clazz, String methodName, final Class[] classes) throws Exception { 
        Method method = null; 
        try { 
            method = clazz.getDeclaredMethod(methodName, classes); 
        } catch (NoSuchMethodException e) { 
            try { 
                method = clazz.getMethod(methodName, classes); 
            } catch (NoSuchMethodException ex) { 
                if (clazz.getSuperclass() == null) { 
                    return method; 
                } else { 
                    method = getMethod(clazz.getSuperclass(), methodName,classes); 
                } 
            } 
        } 
        return method; 
    } 
 
    /**
    * 
     * @param obj
     *            调整方法的对象
     * @param methodName
     *            方法名
     * @param classes
     *            参数类型数组
     * @param objects
     *            参数数组
    * @return 方法的返回值
     */ 
    public static Object invoke(final Object obj, final String methodName,final Class[] classes, final Object[] objects) { 
        try { 
            Method method = getMethod(obj.getClass(), methodName, classes); 
            method.setAccessible(true);// 调用private方法的关键一句话 
            return method.invoke(obj, objects); 
       } catch (Exception e) { 
            throw new RuntimeException(e); 
        } 
    } 
 
    public static Object invoke(final Object obj, final String methodName,final Class[] classes) { 
       return invoke(obj, methodName, classes, new Object[] {}); 
    } 
 
    public static Object invoke(final Object obj, final String methodName) { 
        return invoke(obj, methodName, new Class[] {}, new Object[] {}); 
    } 
 
    /**
     * 测试反射调用
     * 
     * @param args
     */ 
    public static void main(String[] args) { 
       PrivateUtil.invoke(new B(), "printlnA", new Class[] {String.class }, new Object[]{"test"}); 
       PrivateUtil.invoke(new B(), "printlnB"); 
    } 

猜你喜欢

转载自jg543189653.iteye.com/blog/2214441