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

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

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

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

2,

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

3,

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

  1. class   A
  2. {
  3. public  void   show(Vector<Integer> v)  {}
  4. }
  5. 在我们不知道Vector中数据的类型的时候 这时候我们只知道这个方法的名字  和参数的个数 ,我们来获取 范型化的实际类型 。
  6. 我们不可能通过 Vector对应的Class类来反射出  泛型集合中的类型  ,但是 我们却可以通过 这个方法所对应的Method类来实现 。
  7. 具体如下  :
  8. import java.lang.reflect.Method;
  9. import java.lang.reflect.ParameterizedType;
  10. import java.lang.reflect.Type;
  11. import java.util.Vector;
  12. public class Test3
  13. {
  14. public static void main(String []args) throws SecurityException, NoSuchMethodException
  15. {
  16. Method  m=A.class.getMethod("show", Vector.class) ;      //反射获得show方法的Method对象
  17. Type[]t=m.getGenericParameterTypes() ;      //获得范型参数的 一个Type数组  Type是Class类的基类 GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType  这些都是 实现Type的子接口
  18. ParameterizedType p=(ParameterizedType)t[0];     //强制转换成Type的子接口 ParameterizedType类型 因为这个接口又可以获得 范型化集合中元素的类型    System.out.println(p.getRawType());                     //获得集合的类型
  19. System.out.println(p.getActualTypeArguments()[0]);   //获得集合中元素的类型
  20. }
  21. }

利用java反射调用类的的私有方法--转的更多相关文章

  1. 利用Java反射根据类的名称获取属性信息和父类的属性信息

    代码: import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java ...

  2. 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

    作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

  3. Java 反射 调用私有域和方法(setAccessible)

    Java 反射 调用私有域和方法(setAccessible) @author ixenos AccessibleObject类 Method.Field和Constructor类共同继承了Acces ...

  4. 利用Java反射机制对实体类的常用操作工具类ObjectUtil

    代码: ObjectUtil类: import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.Simpl ...

  5. PHP通过反射方法调用执行类中的私有方法

    PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 下面我们演示一下如何通过反射,来调用执行一个类中的私有方法: <?php //MyClass这个类中包 ...

  6. C# 利用反射调用类下的方法

    namespace TestReflection { public partial class Form1 : Form { public Form1() { InitializeComponent( ...

  7. java反射工具类

    package com.yingchao.kgou.core; import java.lang.reflect.Field; import java.lang.reflect.InvocationT ...

  8. Java 反射 分析类和对象

    Java 反射 分析类和对象 @author ixenos 摘要:优化程序启动策略.在运行时使用反射分析类的结构和对象 优化程序启动策略 在启动时,包含main方法的类被加载.它会加载所有它需要的类. ...

  9. 利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils

    有时遇到将数据传输对象转换成JSON串会将属性值为空的属性去掉,利用Java反射实现JavaBean对象数据传输对象的相同属性复制并初始化数据传输对象属性为空的属性,然后转换成JSON串 packag ...

随机推荐

  1. 03-Spring的IOC示例程序(通过类型获取对象)

    根据bean类型从IOC容器中获取bean的实例 ①test测试类 @Test public void Test02() { //获取spring容器对象 ApplicationContext app ...

  2. 01-书城http状态405-此url不支持http方法get

    错误: http状态405-此url不支持http方法get 原因:

  3. JVM系列(三)之GC

    什么是GC Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄 ...

  4. notepad++,vim驼峰命名与下划线的互相转换

    notepad++,vim驼峰命名与下划线的互相转换   IDDAY_TIMEDAY_FULL_NAMEDAY_OF_WEEKYEAR_MONTHYREA_NAME 下滑线转驼峰 大写转小写 有这么些 ...

  5. java -jar命令运行jar包时指定外部依赖jar包 linxux or windows

    前尘回顾: setup.bat [chenquan@hostuser tartest]$ cat ../setup.sh javac -encoding UTF-8 -Djava.ext.dirs=. ...

  6. MySQL主从复制原理的是啥?

    主库将变更写binlog日志,然后从库连接到主库之后,从库有一个IO线程,将主库的binlog日志拷贝到自己本地,写入一个中继日志中. 接着从库中有一个SQL线程会从中继日志读取binlog,然后执行 ...

  7. maven的背景

    本书链接 链接:http://pan.baidu.com/s/1c2fF3Ks 密码:hlce maven是一套软件工程管理和整合工具. 基于工程对象模型的概念(POM),通过一个中央信息管理模块,m ...

  8. POJ-2891 Strange Way to Express Integers(拓展中国剩余定理)

    放一个写的不错的博客:https://www.cnblogs.com/zwfymqz/p/8425731.html POJ好像不能用__int128. #include <iostream> ...

  9. 杨蓉庆201771010135《面向对象程序设计(java)》第一周学习总结

    第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com 艾特大家 程序设计评测:https://pintia.cn/ 艾特你 代码托管平台:h ...

  10. Vue 使用MD5 加密

    第一步: npm安装: npm install --save js-md5 第二步: 全局引用 import md5 from 'js-md5'; Vue.prototype.$md5 = md5; ...