setAccessible 访问控制权限

Java反射与动态代理一文中,见到下边这段话,在此作个记录。

使用Java反射API的时候可以绕过Java默认的访问控制检查,比如可以直接获取到对象的私有域的值或是调用私有方法。只需要在获取到Constructor、Field和Method类的对象之后,调用setAccessible方法并设为true即可。

利用反射,首先是Class对象的获取,之后是Method和Field对象的获取。以Method为例,从文档中可以看到:getMethod()方法返回的是public的Method对象,而getDeclaredMethod()返回的Method对象可以是非public的。Field的方法同理。

 访问私有属性和方法,在使用前要通过AccessibleObject类(Constructor、 Field和Method类的基类)中的setAccessible()方法来抑制Java访问权限的检查

setAccessible,设置是否允许访问,而不是修改原来的访问权限修饰词。主要用于访问私有的内容。默认是false。

 

public class PrivateClass
{
    private String sayHello(String name)
    {
        return "Hello: " + name;
    }

}

访问类

import java.lang.reflect.Method;

public class TestPrivate
{

    public static void main(String[] args) throws Exception
    {
        PrivateClass p = new PrivateClass();

        Class<?> classType = p.getClass();

        // 获取Method对象
        Method method = classType.getDeclaredMethod("sayHello", new Class[] { String.class });

        method.setAccessible(true); // 抑制Java的访问控制检查,默认为false
        // 如果不加上上面这句,将会Error: TestPrivate can not access a member of class PrivateClass with modifiers "private"
        String str = (String) method.invoke(p, new Object[] { "zhangsan" });

        System.out.println(str);
    }
}

 

posted @ 2016-06-01 14:13  milkty  阅读(1611)  评论(0编辑  收藏  举报