通过JAVA的反射调用类中的公有私有方法

文章来源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的反射调用类中的公有私有方法)