JAVA的访问控制3-封装和可访问范围

JAVA的访问控制3-封装和可访问范围

在前文JAVA的访问控制1-访问控制的必要性,包JAVA的访问控制2-public,protected,private和package-private中我们介绍了访问控制的由来,基本概念以及具体内容,这一篇会继续深入一些,讲解一下这几篇文章最开始提到的封装可访问范围的一些内容。

封装

JAVA语言通过访问控制符,给我们提供了一种能力,我们可以控制客户程序员的访问范围,或者说,客户程序员可以只知道这个类可以完成什么,而不需要去关注其实现细节。这样的话,类的创建者就可以将内部的机制隐藏起来,并且,在需要修改的时候,可以放心的修改内部机制,不用担心破坏客户程序员的使用。
封装就是这种能力,有时候这个能力也叫信息隐藏.
封装不只是JAVA语言中可用的一种概念,它是软件设计的一个基本原则之一。封装在软件设计的很多层次都有体现。
在最小的类层次,封装体现为类对外提供一些方法,内部存在自己的实现。
在更大的模块层次,封装体现为整个模块对外提供了哪些能力,外部只能使用这些能力,而不必深入了解模块内部的机制,比如用户模块可能通过一些方法对外提供给了人员的管理能力,其他模块只需要使用这些方法即可,而不必自行去操作用户模块的数据库等内部内容。
在服务层次,体现为整个服务对外提供了哪些能力,一般是通过接口的方式提供,而内部实现(比如数据库)等内容,则不会对外提供。
可以看到,每一层的内容不一样,但是思想是完全一致的,就是把内部很小心的隐藏起来,只对外提供必要的方法,而不是把整个系统全部敞开。
举个反例,如果如果我们要使用某个类,需要提前设置这个类的某个内部变量,然后再用某些方法,那这个就是没有封装的,如果其作者想要修改前面的那个内部变量,势必会影响客户端,导致更大范围的修改,这样的系统就会盘根错节,牵一发而动全身,最终难以维护。
这种就是紧密耦合,会导致软件很难以维护,通过封装可以有效缓解这个问题,做到解耦。
除此以外,封装还可以提高复用性,如果这个类很易于使用,并且提供的功能又很明确,那么其它遇到这一需求的就可以直接使用。如果类封装的不好,使用起来困难重重,很可能会导致其他人不愿意使用,还不如自己写一个新的,复用性也就很差了。

封装与可访问范围

上面介绍了封装和封装可以带来的好处,为了更好的封装,我们需要控制可访问范围。关于控制可访问范围,只有一个原则,那就是,保持可访问范围最小。我们要尽可能的做到,每个内部的变量和方法,都不能被外部访问,对外开放的,也就是设置为public的,仅应是那些必须对外提供的能力。
如果一个方法被设置成public了,那就意味着我们对外做出了一个承诺,public方法的名称,入参,返回值等,一旦发布就难以修改了,后续还需要持续维护它的兼容性,务必谨慎。
类的实例变量,不应该设置为public的,如果需要对外提供,那么可以提供getXXXgetter方法。
另外,如果类的实例变量是可变对象,比如数组,列表,或者是Date这种可变的类,在提供getter方法的时候,要注意保护自己。
内部的变量提供给外部,很可能会被外部篡改,最好是变量本身设置为不可变,或者是克隆一个克隆体给外部,这样外部的类就无法修改类的内部变凉了。出门在外,要当心
下面举一个例子说明这种情况:

public class XxxService {
    private static final String[] FIELDS = {"field1", "field2"};
    public String[] getFields() {
        return FIELDS;
    }
}

这里是一个类,它的内部有一个FIELDS常量,按照定义private static final String[],原意应该是一个不可变的数组,但是使用方没有注意到,而是对它进行了修改:

// 非法使用者:
XxxService xxxService = new XxxService();
String[] fields = xxxService.getFields();
fields[0] = "myField";
// ...

这之后XxxService所有依赖FIELDS的方法都会被破坏,问题还隐藏的很深,并不在XxxService中,难以排查。
很多安全问题也是这样子来的,请务必小心。
要规避也比较简单,返回这个数组的副本就可以了:return Arrays.copyOf(FIELDS, FIELDS.length),这样子使用方即使修改了返回的数组,也就不会对XxxService的功能有影响了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值