java反射取得private函数

http://blog.csdn.net/v_fei/article/details/3720315
今天和一位朋友谈到父类私有方法的调用问题,本来以为利用反射很轻松就可以实现,因为在反射看来根本不区分是否是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");
    }
}
class A {
    private void printlnA(String s) {
        System.out.println(s);
    }
}
class B extends A {
    private void printlnB() {
        System.out.println("b");
    }
}
程序的输出结果为
test
b
说明private方法调用成功了不管是自己的私有方法还是父类的私有方法。

你可能感兴趣的:(java反射取得private函数)