类和接口是Java程序设计语言的核心, 也是Java语言的基本抽象单元.
设计良好的模块会隐藏所有的实现细节,把它的API与它的实现清晰的隔离开来.
访问控制机制决定了类,接口和成员的可访问性.
- 尽可能的使每个类或成员不被外界访问
顶层的(非嵌套)类和接口只有两种访问级别:
- 包级私有的
- 公有的
成员(域, 方法, 嵌套类, 嵌套接口) 有四种访问级别:
- 私有的 private
- 包级私有的 default
- 受保护的 protected
- 公有的 public
访问范围: private < default < protected < public
如果方法覆盖了超类中的一个方法, 子类中的访问级别就不允许低于超类中的访问级别.
这样才可以确保任何可使用超类的实例的地方也都可以使用子类的实例.
实例域决不能是公有的. 一旦是公有的,将放弃了对存储在这个域中的值进行限制的能力.
包含公有可变域的类并不是线程安全的.
同样的建议也适用于静态域,只是有一种例外情况. 假设常量构成了类提供的整个抽象中的一部分,可以通过公有的静态final域来暴露这些常量.
注意, 长度非零的数组总是可变的. 所以, 类具有公有的静态final数组域,或者返回这种域的访问方法,这季候总是错误的.如果类具有公有的静态final的域或访问方法,客户端将能够修改数组中的内容,是一个常见的安全漏洞的根源:
// Potential security hole!
public static final Thing[] VALUES = { ...};
修正方法1:公有数组变为私有的,增加一个公有的不可变列表
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES = Collections.unmodifiablesList(Arrays.asList(PRIVATE_VALUES));
修正方法2:公有数组变为私有的,公有方法返回私有数组的一个备份:
priavate static final Thing[] PRIVATE_VALUES = {...};
public static final Thing[] values() {
return PRIVATE_VALUES.clone();
}
网友评论