通过JAVA的反射调用类中的公有私有方法
程序员文章站
2024-01-20 22:27:22
...
文章来源http://lavasoft.blog.51cto.com/62575/61002及http://blog.csdn.net/sunyujia/article/details/2501709
一直对于JAVA下的反射不是很清楚。虽然自己做J2me和android也做了几年了,实在惭愧。
晚上在查看xmpp下的重连源码时,发现Asmack下有重连机制,但类的构造函数是私有的,也未能找到外部调用的方法。于是想到了用反射来调用,但对于反射不是很熟悉,只好百度找大牛的文章,文章是找到了,但第一篇文章中只实现了调用公有的方法,而私有的方法却未说明,于是又百度找方法,在第二篇文章中找到了,将它记录下来,在这里谢谢两位大牛了;
这是个测试用的例子,通过反射调用对象的方法。取自第一篇文章;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
/**
* Created by IntelliJ IDEA.
* File: TestRef.java
* User: leizhimin
* Date: 2008-1-28 14:48:44
*/
public class TestRef {
public static void main(String args[]) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Foo foo = new Foo("这个一个Foo对象!");
Class clazz = foo.getClass();
Method m1 = clazz.getDeclaredMethod("outInfo");
Method m2 = clazz.getDeclaredMethod("setMsg", String.class);
Method m3 = clazz.getDeclaredMethod("getMsg");
m1.invoke(foo);
m2.invoke(foo, "重新设置msg信息!");
String msg = (String) m3.invoke(foo);
System.out.println(msg);
}
}
class Foo {
private String msg;
public Foo(String msg) {
this.msg = msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void outInfo() {
System.out.println("这是测试Java反射的测试类");
}
}
调用的方法如下:(在main中调用)
Fanshe foo = new Fanshe("这个一个Foo对象!");
Class clazz = foo.getClass();
Method m1 = clazz.getDeclaredMethod("outInfo");
// m1.setAccessible(true); //这句话很重要,对于调用私有方法时需要用到
Method m2 = clazz.getDeclaredMethod("setMsg", String.class);
Method m3 = clazz.getDeclaredMethod("getMsg");
m1.invoke(foo);
m2.invoke(foo, "重新设置msg信息!");
String msg = (String) m3.invoke(foo);
System.out.println(msg);
在JAVA环境下运行没有问题;但当把其中一个方法改成私有的时候,会报安全权限的异常,异常如下:
java.lang.IllegalAccessException: Class TestMain can not access a member of class Fanshe with modifiers "private"
在第二篇文章中找到了解决的方法。解决方法就是注释的那一行,将注释的那行去掉注释后,就可以正常运行了。
对于注释下的那一行,添加了一个String.class的参数。我的理解是,因为setMsg这个方法需要传入一个参数进去,参数类型是string型,所以需要引用到String.class这个类。
若参数换成别的基本类型时,将需要引用到其它基本类型的类。为了验证是不是自己理解的这样子,我将Foo中setMsg();的参数改成了int型,并将测试类中修改参数为int.class,这时测试通过,如自己理解;
上一篇: java插入法排序
下一篇: Reflection 反射