一般情况下,在外部是无法访问私有变量和私有方法的,但是运用反射机制则可以绕过这个限制。
假设有一个A类:
class A{
private String var;
private void methodA(){
System.out.println("the var is" + var);
}
}
我们想要在外部访问它的私有变量和方法,则可以:
A a = new A();
Field field = a.getClass().getDeclaredField("var"); //获取成员变量var的反射类
field.setAccessible(true); //取消语言访问检查,否则会抛出IllegalAccessException。
field.set(a,"abc"); //将对象a的私有变量var赋值为"abc"。
//通过方法getDeclaredMethods(String name,Class... parameterTypes)获取方法的反射类。
//其中parameterTypes是方法的入参类型。
Method method = a.getClass().getDeclaredMethod("methodA",(Class[]) null);
method.setAccessible(ture);
method.invoke(a,(Object[])null); //调用a.methodA()
上述代码的运行结果,可以看到私有变量var被成功设置了,私有方法methodA也会被运行。
需要注意的一点是,setAccessible(true)可以取消java语言访问控制检查,从而允许我们从外部访问对象的私有变量与方法,但是如果当前环境没有相应的权限,JVM则会抛出SecurityException。
相关的JDK文档:
First, if there is a security manager, its checkPermission method is called with a ReflectPermission(“suppressAccessChecks”) permission.
A SecurityException is raised if flag is true but accessibility of this object may not be changed (for example, if this element object is a Constructor object for the class Class).
A SecurityException is raised if this object is a Constructor object for the class java.lang.Class, and flag is true.