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); } }