通过反射破除类的封装性

5 篇文章 0 订阅
3 篇文章 0 订阅

大家都知道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开发

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值