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


    原文:http://blog.csdn.net/woshinia/article/details/11766567

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

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


    程序的输出结果为
    test
    b
    说明private方法调用成功了不管是自己的私有方法还是父类的私有方法。

    2,

    [java] view plaincopy
     
    1. package me.test;  
    2. import java.lang.reflect.*;  //导入反射需要的包  
    3. public class ReflectTest {  
    4.  public static void main(String[] args)  throws  Exception  
    5.  {    
    6.     
    7.   /*  下面通过反射完成对一个对象中成员的替换 
    8.    *   并且执行执行私有方法   
    9.    *   完成对 Poiont类的对象中所有的 String的对象的d换成x 
    10.    *   并且类中无修改方法     
    11.    */   
    12.     Point pt=new Point(3,5);  //创建一个Point对象  
    13.     Field fx=pt.getClass().getField("x") ;  //获取x的映射类对象  
    14.     Field fy=pt.getClass().getDeclaredField("y");//因为y是私有的所以要调用这个方法   
    15.     Method m2=Point.class.getDeclaredMethod("showPrivate") ;//获得私有方法映射类    
    16.       
    17.     //利用反射调用共有输出   
    18.     m2.setAccessible(true)  ;// 修改showPrivate 权限 改变为可以调用  
    19.        m2.invoke(pt) ;//执行私有方法  
    20.     //利用成员反射输出x 和 私有的 y    
    21.     System.out.println(fx.getInt(pt));//反射输出x    
    22.     fy.setAccessible(true) ;//改变私有为可访问  
    23.     System.out.println(fy.getInt(pt));//输出私有y  
    24.           
    25.     //替换成员后并且反射私有方法输出   
    26.     changeString(pt) ;//反射替换成员值  
    27.      System.out.println(pt);  
    28.       
    29.       
    30.  }  
    31.  public static void changeString(Object obj)  throws Exception//反射替换对所有String进行替换  
    32.  {   
    33.   Field[] f=obj.getClass().getFields()  ; //获得成员映射数组  
    34.   for(Field tem : f)  //迭代for循环  
    35.   {  
    36.    if(tem.getType()==String.class)  //内存中只有一份String字节码   
    37.    {  
    38.     String oldString=(String)tem.get(obj) ;  //返回内容  
    39.     String newString=oldString.replace('d', 'x');//将所有b替换为x    
    40.     tem.setAccessible(true);  
    41.      tem.set(obj, newString) ;//替换成员值  
    42.    }  
    43.      
    44.   }  
    45.     
    46.  }  
    47. }  
    48.   
    49. public class Point  
    50. {  
    51.  public int x  ;  
    52.  private int y  ;  
    53.  public Point(int x, int y) {  
    54.   super();  
    55.   this.x = x;  
    56.   this.y = y;  
    57.  }  
    58.    public String  a="dsfdsfd"  ;  //只有 共有可以替换  
    59.    public String  b="fdsfdsfewewwwww"  ;  
    60.    public String  c="adddssss"  ;  
    61.   
    62.  private void showPrivate()  //私有方法输出  
    63.  {  
    64.   System.out.println("x="+this.x+" "+"y="+this.y);  
    65.   System.out.println(this.a);  
    66.   System.out.println(this.b);  
    67.   System.out.println(this.c);   
    68.  }  
    69.   
    70.  public String toString()  
    71.  {  
    72.   return this.a+" "+this.b+" "+this.c;  
    73.  }  
    74.   
    75. }  


    3,  

    Java利用反射来获取一个方法的 范型化参数 Vector<Integer>的类型

    [java] view plaincopy
     
    1. class   A  
    2.   
    3. {  
    4.   
    5.      public  void   show(Vector<Integer> v)  {}  
    6. }    
    7.   
    8. 在我们不知道Vector中数据的类型的时候 这时候我们只知道这个方法的名字  和参数的个数 ,我们来获取 范型化的实际类型 。   
    9.   
    10. 我们不可能通过 Vector对应的Class类来反射出  泛型集合中的类型  ,但是 我们却可以通过 这个方法所对应的Method类来实现 。  
    11.   
    12. 具体如下  :  
    13.   
    14. import java.lang.reflect.Method;  
    15. import java.lang.reflect.ParameterizedType;  
    16. import java.lang.reflect.Type;  
    17. import java.util.Vector;  
    18.   
    19. public class Test3  
    20. {  
    21.  public static void main(String []args) throws SecurityException, NoSuchMethodException  
    22.  {  
    23.   Method  m=A.class.getMethod("show", Vector.class) ;      //反射获得show方法的Method对象  
    24.   Type[]t=m.getGenericParameterTypes() ;      //获得范型参数的 一个Type数组  Type是Class类的基类 GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType  这些都是 实现Type的子接口   
    25.   ParameterizedType p=(ParameterizedType)t[0];     //强制转换成Type的子接口 ParameterizedType类型 因为这个接口又可以获得 范型化集合中元素的类型    System.out.println(p.getRawType());                     //获得集合的类型    
    26.   System.out.println(p.getActualTypeArguments()[0]);   //获得集合中元素的类型  
    27.  }  
    28.   
    29. }  
  • 相关阅读:
    时间计算
    DateTime
    C# trim split dataGrid
    something
    生活
    如何导入外部的源码到eclipse中
    java类中获取ServletContext的方法
    获取spring容器上下文(webApplicationContext)的几种方法
    java反射(转)
    mysql常见命令
  • 原文地址:https://www.cnblogs.com/mochaMM/p/5016431.html
Copyright © 2020-2023  润新知