怎样通过反射机制调取内部类的私有方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样通过反射机制调取内部类的私有方法相关的知识,希望对你有一定的参考价值。

externalClass externalObj= new externalClass();
Class external=externalObj.getClass();
Class inner=external.forName("com.api.business.externalClass$innerClass");
Method method=inner.getDeclaredMethod("innerMethod");
method.setAccessible(true);
Object innerObj=inner.newInstance();
method.invoke(innerObj);

invoke方法会报错。。。求大神指教!
class externalClass
private class innerClass
pulic innerClass()

private void innerMethod()
System.out.println("test");



不好意思啊,我没怎么懂。另外,我问的内部类的私有办法,并非继承。现在问题是invoke执行的时候,会报找不到这个对象。。。求大牛指教

######
找到解决方法了,的确是因为没有生成对象,报了个很诡异的错:说是找不到构造器。
可以用以下方法获取内部类的对象,其他不变。
Object innerObj=inner.getConstructors()[0].newInstance(new externalClass());

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方法调用成功了不管是自己的私有方法还是父类的私有方法。追问

不好意思啊,有字数限制,请看问题补充。

参考技术A   package com.syj.util.reflect; import java.lang.reflect.Method; /** * <p> * Title: 私有方法调用工具类
  反射是一种自然现象,表现为受刺激物对刺激物的逆反应。.反射的外延宽泛。物理学领域是指声波、光波或其他电磁波遇到别的媒质分界面而部分仍在原物质中传播的现象;生物学领域里反射是在中枢神经系统参与下,机体对内外环境刺激所作出的规律性反应。计算机领域中反射是提供封装程序集、模块和类型的对象;电子领域中就是在传输线上的回波。研究反射产生机制,,把握反射规律,有利于人类更好的利用反射进行各种相关工作。其应用领域是相当广泛的。

使用反射机制调用属性和私有成员与代理模式的介绍

使用反射机制调用属性:

通过反射机制可以获得类的属性,获得到的属性同样的可以进行赋值、得值操作,调用getField方法并传递属性的名称可以获得【学Java,到凯哥学堂kaige123.com】指定的属性,调用getFields方法则可以获得全部属性,但是这种方式不能获得私有属性: 代码示例:

image

Student类示例:

image

运行结果:

image

从运行结果可以看出只拿出了公开的属性,私有的属性拿不到。

使用反射机制调用私有成员:

1.调用私有属性

在反射机制里调用私有属性需要通过getDeclaredFields方法或者getDeclaredField方法,前者是获得类里所有的私有属性,后者是获得指定的私有属性,类似于getFields和getField。但是使用getDeclaredFields或者getDeclaredField方法获得私有属性之后需要再调用setAccessible方法进行一个调用授权的操作才能对获得到的私有属性进行操作: 代码示例:

image

Student代码示例:

image

运行结果:

image

2.调用私有方法 调用私有方法也是一样的,需要先通过getDeclaredMethods方法或者getDeclaredMethod方法来获得私有方法,然后还得再调用setAccessible方法进行调用授权: 代码示例:

image

Student代码示例:

image

运行结果:

image

3.调用私有构造器

image

Student代码示例:

image

运行结果:

image

代理模式: 代理模式又称为切面编程,顾名思义就是可以把代码切开一个缝隙塞入一些代码,代理模式可以在方法的前后监控异常,也可以把日志打印语句放在代理里,方法里就不需要写日志打印的语句了,资源的开启和关闭这种重复次数多的的代码也可以写在代理里,同样的在方法里就不需要再写了,所以代理模式类似于中介一样,在代码中间解决一些反复而常规的代码。 编写代理模式的代码,第一步是写一个接口声明一个方法,第二步写一个A类去实现这个接口,在方法里写上一些代码,第三步写一个B类,这个类也要实现接口,并且在这个类的属性上声明接口的变量,构造器里声明接口类型的参数,用于把对象存储到属性里,接着在重写接口的方法里调用A实现类里的方法,第四步写运行类,在main方法里首先new A类的对象出来,然后new B 类的对象并且把A类的对象放进B类的构造器里,最后用B类的对象调用方法。 代码示例:

image

image

image

image

运行结果:

image

代码图解:

image

还可以使用继承的方式编写代理模式,但是继承有个弊端,万一这个类不允许被继承(final修饰的类),或者还需要继承其他的类(Java只能单一继承),那么就无法编写代理模式,因为接口可以实现多个,所以使用接口是最好的。 代码示例:

image

image

image

运行结果:

image

代码图解:

image

以上是关于怎样通过反射机制调取内部类的私有方法的主要内容,如果未能解决你的问题,请参考以下文章

反射学习3-通过反射机制修改类中的私有属性的值

一文让你读懂“反射机制”!

使用反射机制调用属性和私有成员与代理模式的介绍

使用反射机制调用属性和私有成员与代理模式的介绍

Java反射机制

反射机制--总结