最近经常使用final字段,final确实存在有一些局限性。尽管数组引用能被声明成 final,但是该数组的元素却不能。这意味着暴露 public final 数组字段的或者通过它们的方法将引用返回给这些字段的类(例如,代码中所示的 Fruit 类)都不是不可改变的。同样,尽管对象引用可以被声明成 final 字段,而它所引用的对象仍可能是可变的。如果您想要使用final 字段创建不变的对象,您必须防止对数组或可变对象的引用“逃离”您的类。要不用重复克隆该数组做到这一点,一个简单的方法是将数组转变成 List,例如代码中所示Food 类:清单暴露数组引用使类成为可变的。- // 下面是例子:
- public class Fruit{
- private final String[] names = new String[] { "apple", "orange", ... };
- public String[] getNames() {
- return names;
- }
- }
- public class Food{
- private final String[] names = new String[] { "rice", "meat", ... };
- private final List namesAsList
- = new AbstractList() {
- public Object get(int n) {
- return names[n];
- }
- public int size() {
- return names.length;
- }
- };
-
- public List getNames() {
- return namesAsList;
- }
- }
复制代码 为什么不继承 final 以应用于数组和引用的对象,类似于 C 和 C++ 中 const 的使用那样呢?C++ 中 const 的语义和使用相当混淆,根据它在表达式中所出现的位置表示不同的东西。Java 设法把我们从这种混淆中“解救”出来,但遗憾的是在这个过程中产生出了一些新的混淆。 |