Effective Java 第13条 : 使类和成员的可访问性最小化

转载地址: http://www.blogjava.net/kuuyee/archive/2013/06/14/400560.html


软件设计的基本原则之一,就是系统要模块化,模块之间只通过他们的API进行通信,一个模块不需要知道其他模块的内部工作情况,这个概念称作信息隐藏(information hiding)或封装(encapsulation)。

需要遵守的原则
  • 尽可能地使每个类或成员不被外界访问。换句话说,应该使用与你正在编写的软件的对应功能相一致、尽可能最小的访问级别。

  • 对于顶层的(非嵌套的)类和接口,只有两种可能非访问级别,要从是包级私有的也就是default,要么是public的.包级私有就意味着它是这个包实现的一部分,不会作为该包API被导出,这样在以后的发型版本中,对它修改、替换、删除就不用担心会影响先有客户端的程序。

  • 如果一个包级私有的顶层类(或者接口)只是在某一个类内部被用到,就应该考虑把它变成唯一使用它的那个类的私有嵌套类。

  • 降低不必要公有类的可访问性,比降低包级私有的顶层类更重要的多,因为共有类是API的一部分,而包级私有的顶层类已经是包实现的一部分了。

  • 受保护(protected)的类或成员是导出API的一部分,必须永远得到支持,应该避免尽量少用。

  • 如果子类覆盖了超类的一个方法,子类中的访问级别就不允许低于超类中的访问级别,否则会编译错误。实现了接口的所有方法也必须是共有的,因为接口中的所有方法都是隐含着共有访问级别。

  • 为了便于测试,不应该把其访问级别成为共有的,取而代之是把测试类成为包的一部分,从而能够访问它的包级私有元素。

  • 实例域决不能是共有的,包含公有可变域的类即便是final的也不是线程安全的

Note长度非零的数组总数可变的,所以,类具有公有的静态final数组域,或者返回这种域的访问方法,这几乎总数错误的。

public class UnmodifiableArray {
// 潜在安全漏洞
public static final String[] VALUES = { "RED", "GREEN" };

public static void main(String[] args) {
UnmodifiableArray UF = new UnmodifiableArray();
UF.VALUES[1] = "YELLO";//设置final数组成员
System.out.println(UF);
}
//使用Guava
@Override
public String toString() {
return Objects.toStringHelper(this).add("VALUES0", UnmodifiableArray.VALUES[0])
.add("VALUES1", UnmodifiableArray.VALUES[1]).toString();
}
}

上面的例子里,我们成功更改了一个不可变数组,把成员GREEN修改为YELLO,执行输出如下:

UnmodifiableArray{VALUES0=RED, VALUES1=YELLO}

我们可以通过增加一个不可变集合列表来解决这个安全问题,并把原来public访问级别改为private的:

public class UnmodifiableArrayList {
// 消除安全漏洞
private static final String[] PRIVATE_VALUES = { "RED", "GREEN" };
public static final List<String> PVALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
public static void main(String[] args) {
UnmodifiableArrayList UF = new UnmodifiableArrayList();
UF.PVALUES.add(1, "YELLO"); //会抛出UnsupportedOperationException异常
System.out.println(UF);
}
//使用Guava
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("PVALUES0", UnmodifiableArrayList.PVALUES.get(0))
.add("PVALUES1", UnmodifiableArrayList.PVALUES.get(1))
.toString();
}
}

构建一个不可变集合,Guava给出了更简洁的办法:

ImmutableList mmutableList = ImmutableList.of(PRIVATE_VALUES);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值