大家都知道JAVA中为了保持类的封装性,往往用private修饰属性,然后public定义set和get方法;
下面看一段代码,首先定义一个Book类:
package pojo;
/**
* Created by ZhuHao on 2018/10/8
*/
public class Book {
private String title;
private double price;
public Book(){
}
public Book(String title,double price){
this.title = title;
this.price = price;
}
public void setTitle(String title){
this.title = title;
}
public String getTitle(){
return this.title;
}
public void setPrice(double price){
this.price = price;
}
public double getPrice(){
return this.price;
}
}
然后编写一个类测试,该类通过反射获得Book类的实例后获得类的属性并尝试直接修改:
public class TestDemo {
public static void main(String[] args) throws Exception{
Class cls = Class.forName("pojo.Book");
Object obj = cls.newInstance();
Field titleField = cls.getDeclaredField("title");
titleField.set(obj,"Java开发");
System.out.println(titleField.get(obj));
}
}
运行结果如下所示,可以看到报异常,显示测试类无法访问private属性:
Exception in thread "main" java.lang.IllegalAccessException: Class TestDemo can not access a member of class pojo.Book with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Field.set(Field.java:761)
at TestDemo.main(TestDemo.java:18)
Process finished with exit code 1
然后我们在TestDemo类中加一句
titleField.setAccessible(true);
该方法属于AccessibleObject,而java.lang.reflect.Field是java.lang.reflect.AccessibleObject的子类,设为true后禁用了JAVA的权限控制检查,代码如下:
public class TestDemo {
public static void main(String[] args) throws Exception{
Class cls = Class.forName("pojo.Book");
Object obj = cls.newInstance();
Field titleField = cls.getDeclaredField("title");
titleField.setAccessible(true);//取消封装
titleField.set(obj,"Java开发");
System.out.println(titleField.get(obj));
}
}
运行后控制台输出:
Java开发