在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
的{{1}}类型的新对象。我们随后克隆result
,尽管result.elements
类将Stack
定义为私有成员。发生了什么,为什么允许?
答案 0 :(得分:3)
private
成员只能从同一个班级的其他成员看到,尤其是在同一个实例中。
编辑:
投票结束 private修饰符强制执行Encapsulation原则。以下是similar question about C#的引用,但原则是相同的。
private
修饰符强制执行封装原则。这个想法是“外部世界”。不应该对AClass进行更改 内部流程,因为AClass实现可能会随着时间而改变 (你必须改变整个外部世界来修复它 实施方面的差异 - 这几乎是不可能的。)
当AClass的实例访问其他AClass实例的内部时 - 你可以确定这两个实例总是知道细节 AClass的实现。如果是AClass内部逻辑流程 已更改 - 您所要做的就是更改AClass的代码。
此外,允许覆盖equals()
或compareTo()
,而不必公开其评估中涉及的属性。
答案 1 :(得分:0)
根据语言规范允许这样做。私有访问意味着对同一CLASS的实例可以看到字段或方法,而不仅仅是实例。
这对某些方法(如克隆)没有特殊权限,但对于同一类中的任何方法都没有。