利用java反射调用类的的私有方法

今天和一位朋友谈到父类私有方法的调用问题,本来以为利用反射很轻松就可以实现,因为在反射看来根本不区分是否是private的,没有想到调用本身的私有方法是可以的,但是调用父类的私有方法则不行,后来纠其原因很有可能是因为getDeclaredMethod方法和getMethod方法并不会查找父类的私有方法,于是只好自己写递归了,经过尝试果然如此。把代码放出来方便更多人。这段代码可以解决很多实际问题,不过利用反射来做的话性能不会太好。

  1. package  com.syj.util.reflect;  
  2.   
  3. import  java.lang.reflect.Method;  
  4. /**  
  5.  * <p>  
  6.  * Title: 私有方法调用工具类  
  7.  * </p>  
  8.  *   
  9.  * <p>  
  10.  * Description:利用java反射调用类的的私有方法  
  11.  * </p>  
  12.  *   
  13.  * <p>  
  14.  * Copyright: Copyright (c) 2007  
  15.  * </p>  
  16.  *   
  17.  * @author 孙钰佳  
  18.  * @main [email protected]  
  19.  * @date Jun 1, 2008 10:18:58 PM  
  20.  */   
  21. public   class  PrivateUtil {  
  22.     /**  
  23.      * 利用递归找一个类的指定方法,如果找不到,去父亲里面找直到最上层Object对象为止。  
  24.      *   
  25.      * @param clazz  
  26.      *            目标类  
  27.      * @param methodName  
  28.      *            方法名  
  29.      * @param classes  
  30.      *            方法参数类型数组  
  31.      * @return 方法对象  
  32.      * @throws Exception  
  33.      */   
  34.     public   static  Method getMethod(Class clazz, String methodName,  
  35.             final  Class[] classes)  throws  Exception {  
  36.         Method method = null ;  
  37.         try  {  
  38.             method = clazz.getDeclaredMethod(methodName, classes);  
  39.         } catch  (NoSuchMethodException e) {  
  40.             try  {  
  41.                 method = clazz.getMethod(methodName, classes);  
  42.             } catch  (NoSuchMethodException ex) {  
  43.                 if  (clazz.getSuperclass() ==  null ) {  
  44.                     return  method;  
  45.                 } else  {  
  46.                     method = getMethod(clazz.getSuperclass(), methodName,  
  47.                             classes);  
  48.                 }  
  49.             }  
  50.         }  
  51.         return  method;  
  52.     }  
  53.   
  54.     /**  
  55.      *   
  56.      * @param obj  
  57.      *            调整方法的对象  
  58.      * @param methodName  
  59.      *            方法名  
  60.      * @param classes  
  61.      *            参数类型数组  
  62.      * @param objects  
  63.      *            参数数组  
  64.      * @return 方法的返回值  
  65.      */   
  66.     public   static  Object invoke( final  Object obj,  final  String methodName,  
  67.             final  Class[] classes,  final  Object[] objects) {  
  68.         try  {  
  69.             Method method = getMethod(obj.getClass(), methodName, classes);  
  70.             method.setAccessible(true ); // 调用private方法的关键一句话   
  71.             return  method.invoke(obj, objects);  
  72.         } catch  (Exception e) {  
  73.             throw   new  RuntimeException(e);  
  74.         }  
  75.     }  
  76.   
  77.     public   static  Object invoke( final  Object obj,  final  String methodName,  
  78.             final  Class[] classes) {  
  79.         return  invoke(obj, methodName, classes,  new  Object[] {});  
  80.     }  
  81.   
  82.     public   static  Object invoke( final  Object obj,  final  String methodName) {  
  83.         return  invoke(obj, methodName,  new  Class[] {},  new  Object[] {});  
  84.     }  
  85.   
  86.       /**
         * 测试反射调用
         * 
         * @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,Yahoo)