文章来源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.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,这时测试通过,如自己理解;