当EffectiveJava遇见Guava - 使类和成员的可访问性最小化(规则13)


软件设计的基本原则之一,就是系统要模块化,模块之间只通过他们的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);

2013-06-14

posted on 2013-06-14 17:09 kuuyee 阅读(2908) 评论(1)  编辑  收藏 所属分类: JEE

评论

# re: 当EffectiveJava遇见Guava - 使类和成员的可访问性最小化(规则13) 2014-09-15 17:41 廊坊网站建设

路过下,围观博主高谈论扩,笑看人生  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2013年6月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

统计

随笔分类(139)

Linux内核

搜索

积分与排名

最新评论

阅读排行榜