欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-01-20 22:27:22
...

文章来源http://lavasoft.blog.51cto.com/62575/61002http://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,这时测试通过,如自己理解;