学习中心
登录
已解决
关于反射是否破坏封装性?

面向对象三大特性之一封装:

封装概念:

封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。

面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。

封装是一种信息隐藏技术,在java中通过关键字private,protected和public实现封装。

什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。 适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。

代码:

public class Student {
    public String name;//姓名
    private int sno;//学号
    private String sex;//性别

    //构造器
	public Student(String name, int sno, String sex) {
        this.setName(name);
        this.setSno(sno);
       	this.setSex(sex);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSno() {
        return sno;
    }

    //对学号进行处理
    public void setSno(int sno) {
        if (sno >0 && sno < 1000)  this.sno = sno;
        else throw new RuntimeException("学号超出范围!");
    }

    public String getSex() {
        return sex;
    }

    //对性别进行处理
    public void setSex(String sex) {
        if ("男".equals(sex) || "女".equals(sex)) this.sex = sex;
        else throw new RuntimeException("性别格式错误!");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sno=" + sno +
                ", sex='" + sex + '\'' +
                '}';
    }
}

我将姓名、学号和性别进行封装,通过set和get方法接口来给外部调用,来达到数据的安全性。其中在设置学号和性别时,对参数进行了限制处理。

反射概念:

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

我的理解是通过反射机制,通过类字节码信息可以操作相应类里的任意属性和方法,包括被private修饰的属性和方法。

那么反射是否破坏封装性?

网上解释:

封装,是将具体的实现细节隐藏,而把功能作为整体提供给类的外部使用,也就是说,公有方法能够完成类所具有的功能。当别人使用这个类时,如果通过反射直接调用私有方法,可能根本实现不了类的功能,甚至可能会出错,因此通过反射调用私有方法可以说是没有任何用处的,开发人员没有必要故意去破坏封装好的类。从这点上看,封装性并没有被破坏。

代码:

public static void main(String[] args) throws Exception {
    //1:通过new方法创建一个Student对象。
    Student student = new Student("小宝贝",123,"女");
    System.out.println("原始数据:"+student);//结果:Student{name='小宝贝', sno=123, sex='女'}

    //2:获取Stuent类的字节码信息对象
    Class cls = Class.forName("cn.indexout.reflectTest03.Student");

    //3:获取私有属性sno,sex
    Field sno = cls.getDeclaredField("sno");
    Field sex = cls.getDeclaredField("sex");
    sno.setAccessible(true);//true的值表示反射对象应该在使用时抑制Java语言访问检查。
    sex.setAccessible(true);

    //4:student对象的sno和sex赋值
    sno.set(student,-1000);//设置小于0
    sex.set(student,"emmm");

    System.out.println("反射后数据:"+student);//结果:Student{name='小宝贝', sno=-1000, sex='emmm'}
}

结果:

0d924387d16d199f693fd71e9a7b85cd.png

**个人理解:**在代码中,通过反射直接给私有属性赋值,破坏了数据的安全性。反射也可以直接调用私有方法,也可能会破坏数据的安全性。那么反射是不是可以说破坏了封装性。

**我感觉:**开发人员没有必要故意去破坏封装好的类,这句话就在强行解释反射是否破封装性。

那么最后,反射没有破坏封装性要怎么解释呢?

244 1
    1个回答
    你还没有查看该回答的权限哦~请先获取查看权限
    立即查看
    写回答