利用java反射调用类的的私有方法--转
原文:http://blog.csdn.net/woshinia/article/details/11766567
1,今天和一位朋友谈到父类私有方法的调用问题,本来以为利用反射很轻松就可以实现,因为在反射看来根本不区分是否是private的,没有想到调用本身的私有方法是可以的,但是调用父类的私有方法则不行,后来纠其原因很有可能是因为getDeclaredMethod方法和getMethod方法并不会查找父类的私有方法,于是只好自己写递归了,经过尝试果然如此。把代码放出来方便更多人。这段代码可以解决很多实际问题,不过利用反射来做的话性能不会太好。
- package com.syj.util.reflect;
- import java.lang.reflect.Method;
- /**
- * <p>
- * Title: 私有方法调用工具类
- * </p>
- *
- * <p>
- * Description:利用java反射调用类的的私有方法
- * </p>
- *
- * <p>
- * Copyright: Copyright (c) 2007
- * </p>
- *
- * @author 孙钰佳
- * @main sunyujia@yahoo.cn
- * @date Jun 1, 2008 10:18:58 PM
- */
- 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方法调用成功了不管是自己的私有方法还是父类的私有方法。\
2,
- package me.test;
- import java.lang.reflect.*; //导入反射需要的包
- public class ReflectTest {
- public static void main(String[] args) throws Exception
- {
- /* 下面通过反射完成对一个对象中成员的替换
- * 并且执行执行私有方法
- * 完成对 Poiont类的对象中所有的 String的对象的d换成x
- * 并且类中无修改方法
- */
- Point pt=new Point(3,5); //创建一个Point对象
- Field fx=pt.getClass().getField("x") ; //获取x的映射类对象
- Field fy=pt.getClass().getDeclaredField("y");//因为y是私有的所以要调用这个方法
- Method m2=Point.class.getDeclaredMethod("showPrivate") ;//获得私有方法映射类
- //利用反射调用共有输出
- m2.setAccessible(true) ;// 修改showPrivate 权限 改变为可以调用
- m2.invoke(pt) ;//执行私有方法
- //利用成员反射输出x 和 私有的 y
- System.out.println(fx.getInt(pt));//反射输出x
- fy.setAccessible(true) ;//改变私有为可访问
- System.out.println(fy.getInt(pt));//输出私有y
- //替换成员后并且反射私有方法输出
- changeString(pt) ;//反射替换成员值
- System.out.println(pt);
- }
- public static void changeString(Object obj) throws Exception//反射替换对所有String进行替换
- {
- Field[] f=obj.getClass().getFields() ; //获得成员映射数组
- for(Field tem : f) //迭代for循环
- {
- if(tem.getType()==String.class) //内存中只有一份String字节码
- {
- String oldString=(String)tem.get(obj) ; //返回内容
- String newString=oldString.replace('d', 'x');//将所有b替换为x
- tem.setAccessible(true);
- tem.set(obj, newString) ;//替换成员值
- }
- }
- }
- }
- public class Point
- {
- public int x ;
- private int y ;
- public Point(int x, int y) {
- super();
- this.x = x;
- this.y = y;
- }
- public String a="dsfdsfd" ; //只有 共有可以替换
- public String b="fdsfdsfewewwwww" ;
- public String c="adddssss" ;
- private void showPrivate() //私有方法输出
- {
- System.out.println("x="+this.x+"\n"+"y="+this.y);
- System.out.println(this.a);
- System.out.println(this.b);
- System.out.println(this.c);
- }
- public String toString()
- {
- return this.a+"\n"+this.b+"\n"+this.c;
- }
- }
3,
Java利用反射来获取一个方法的 范型化参数 Vector<Integer>的类型
- class A
- {
- public void show(Vector<Integer> v) {}
- }
- 在我们不知道Vector中数据的类型的时候 这时候我们只知道这个方法的名字 和参数的个数 ,我们来获取 范型化的实际类型 。
- 我们不可能通过 Vector对应的Class类来反射出 泛型集合中的类型 ,但是 我们却可以通过 这个方法所对应的Method类来实现 。
- 具体如下 :
- import java.lang.reflect.Method;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- import java.util.Vector;
- public class Test3
- {
- public static void main(String []args) throws SecurityException, NoSuchMethodException
- {
- Method m=A.class.getMethod("show", Vector.class) ; //反射获得show方法的Method对象
- Type[]t=m.getGenericParameterTypes() ; //获得范型参数的 一个Type数组 Type是Class类的基类 GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType 这些都是 实现Type的子接口
- ParameterizedType p=(ParameterizedType)t[0]; //强制转换成Type的子接口 ParameterizedType类型 因为这个接口又可以获得 范型化集合中元素的类型 System.out.println(p.getRawType()); //获得集合的类型
- System.out.println(p.getActualTypeArguments()[0]); //获得集合中元素的类型
- }
- }
利用java反射调用类的的私有方法--转的更多相关文章
- 利用Java反射根据类的名称获取属性信息和父类的属性信息
代码: import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java ...
- 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换
作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...
- Java 反射 调用私有域和方法(setAccessible)
Java 反射 调用私有域和方法(setAccessible) @author ixenos AccessibleObject类 Method.Field和Constructor类共同继承了Acces ...
- 利用Java反射机制对实体类的常用操作工具类ObjectUtil
代码: ObjectUtil类: import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.Simpl ...
- PHP通过反射方法调用执行类中的私有方法
PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 下面我们演示一下如何通过反射,来调用执行一个类中的私有方法: <?php //MyClass这个类中包 ...
- C# 利用反射调用类下的方法
namespace TestReflection { public partial class Form1 : Form { public Form1() { InitializeComponent( ...
- java反射工具类
package com.yingchao.kgou.core; import java.lang.reflect.Field; import java.lang.reflect.InvocationT ...
- Java 反射 分析类和对象
Java 反射 分析类和对象 @author ixenos 摘要:优化程序启动策略.在运行时使用反射分析类的结构和对象 优化程序启动策略 在启动时,包含main方法的类被加载.它会加载所有它需要的类. ...
- 利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils
有时遇到将数据传输对象转换成JSON串会将属性值为空的属性去掉,利用Java反射实现JavaBean对象数据传输对象的相同属性复制并初始化数据传输对象属性为空的属性,然后转换成JSON串 packag ...
随机推荐
- warmup
先简单了解下源码中的2个函数: <?php echo mb_strpos("朋友比生命还重要?或许是吧" . '?',"?"); echo "\ ...
- bm坏字符 , Horspool算法 以及Sunday算法的不同
bm坏字符 , Horspool算法 以及Sunday算法的不同 一.bm中的坏字符规则思想 (1)模式串与主串从后向前匹配 (2)发现坏字符后,如果坏字符不存在于模式串中:将模式串的头字符与坏字符后 ...
- 制作PPT时的一些技巧记录
1.当一页PPT上有很多图片,要选择其中一张图片时,发现图片都重叠了,不好选择时该怎么办? 2.对动画的编辑 技巧:与选择窗口配合使用
- C:作用域
作用域 C语言变量的作用域分为: 代码块作用域(代码块是{}之间的一段代码) 函数作用域 文件作用域 局部变量 局部变量也叫auto自动变量(auto可写可不写),一般情况下代码块{}内部定义的变量都 ...
- numpy函数hstack,vstack,dstack简介
vstack.hstack和dstack都用于把几个小数组合并成一个大数组.它们的差别是小数组的元素在大数组中的排列顺序有所不同.把两部手机摆到一起有几种方式?水平的左右排列,垂直的上下排列,还可以把 ...
- 安装和配置Windows系统虚拟机
1.打开虚拟机软件,点击新建虚拟机. 2.选择典型配置,点击下一步. 3.点击安装程序光盘映像文件,选择对应的映像文件,然后点击下一步.选择对应的密钥和版本,设置密码等. 4.创建虚拟机名字和存储位置 ...
- wcftestclient test soap API
soap 类API测试方法: 1. 打开developer command prompt, 输入:wcftestclient 2. 选中“My Service Project”, 再Add servi ...
- PTA喊山
喊山 喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤.呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的.原来它是彝族 ...
- 分享Linux系统快速入门法
相信看到这篇文章的你一定是想要学习Linux,或者已经在学习Linux的人了,那我们就可以一起探讨一下,学习Linux如何快速入门呢? 首先,希望大家弄清楚自己为什么要学习Linux,有的人是因为兴趣 ...
- git 工具常见命令
1.git是什么 git是分布式版本管理工具,一台电脑既可以是客户端,也可以是服务端.工作过程中可以断开网络. git中的三个概念: 1.版本库:在初始化git版本库之后会生成一个隐藏的文件, .gi ...