有效Java: clone() 私有访问

Effective Java: clone() private access

在 Bloch 的 Effective Java,第 2 版中,项目 11:明智地覆盖克隆 有以下示例:

class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;
    public Stack() {
        this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }
    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }
    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null; // Eliminate obsolete reference
        return result;
    }
    // Ensure space for at least one more element.
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }

    @Override public Stack clone() {
        try {
            Stack result = (Stack) super.clone();
            result.elements = elements.clone();
            return result;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

如您所见,在 clone() 方法中,创建了一个类型为 Stack 的新对象,称为 result。我们随后克隆 result.elements,尽管 Stack class 将 elements 定义为私有成员。这是怎么回事,为什么允许这样做?

private 成员仅对同一 class 中的其他成员可见,尤其是在同一实例中。

编辑:

否决票 private 修饰符强制执行封装原则。

这里引用similar question about C#但原理是一样的

The private modifier enforces Encapsulation principle.

The idea is that 'outer world' should not make changes to AClass internal processes because AClass implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).

When instance of AClass accesses internals of other AClass instance - you can be sure that both instances always know the details of implementation of AClass. If the logic of internal to AClass processes is changed - all you have to do is change the code of AClass.

此外,还允许覆盖 equals()compareTo(),而不必公开评估中涉及的属性。

根据语言规范,这是允许的。私有访问意味着字段或方法对同一 CLASS 的实例可见,而不是仅对实例可见。

这不是对某些方法(如克隆)的特殊许可,而是对同一 class 中的任何方法的特殊许可。