有效的Java声称elements.clone()就足够了

justgivememyicecream:

我在读约书亚布洛赫的有效的Java,第二版明智覆盖克隆:11项。

在56页,他试图解释,当我们重写clone()了一些类(比如集合类),我们必须复制它的内部然后,他给了设计一个类的实例Stack

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;
    public Stack() {...}
    public void push(Object e) {...}
    public Object pop() {...}
    private void ensureCapacity() {...} //omitted for simplicity
}

他声称,如果我们简单地使用super.clone()克隆Stack,所产生的协议栈实例“将在它的大小字段中输入正确的值,但它的元素域将指向同一个数组作为原始栈实例。修改原来会破坏不变的克隆,反之亦然。你很快就会发现,你的程序产生无意义的结果或抛出一个NullPointerException“。现在,似乎是公平的。但他接着给出了“正确执行”,这让我困惑的一个例子:

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

现在是如何从不同super.clone()我知道,新的Stack.element会比旧的和所有不同的参考; 但数组的“内部”仍然是相同的,不是吗?数组的实际元素result.element仍指向原始Object引用。这可能还导致改变原来的,反之当反之亦然销毁克隆的不变量,不能呢?我错过了什么?

扫路机:

你是绝对正确的关于如何clone工作。背衬数组中的对象将不被复制,但是背衬阵列将被复制。

这不是一个问题,因为主叫方没有预料的元素被无论如何都会被复制。对于集合类,如堆栈,该“规范”是做一个浅拷贝。从标准库的一个例子是拷贝构造函数ArrayList

另外请注意,您可以实现clone通过克隆阵列内的对象,以及(这将意味着堆栈只能存储Clonable暴露的对象clone)。这将不会打破的合同clone合同是非常宽松的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有效的Java:clone()方法的分析

单击邮件中的恶意链接后,没有启动检查就足够了吗?

在gradle中,我应该排除分支下的所有依赖项还是仅根就足够了?

仅为iPhone上的所有版本提供3x图像就足够了吗?

一本Java书籍足够了还是我应该首先学习算法?

java.util.regexp是否足够有效?

定期调度AWS Glue搜寻器有什么用。一次运行就足够了

有一个想法,但我不确定如何去做,如果单独使用 django 就足够了?

collectionAndThen方法足够有效吗?

Twitter Android-FirebaseUI身份验证:一旦我拥有Android App上的访问令牌和访问密钥,如何代表用户发布?足够了吗?

为了使自定义类的对象具有可比性,仅定义__eq__和__lt__系列中的几个成员就足够了吗?

多少个null检查就足够了?

多个 API 变体或 1 个就足够了?

Activiti和Drools ...就足够了吗?

一个NavigatorController就足够了吗?

当“operator <=>”就足够了时,为什么我必须提供“operator ==”?

Web服务安全性-足够了吗?

我是否需要声明按钮以及onCreate()或“ setid”就足够了?

PostgreSQL应该离开联接使用WHERE或ON就足够了吗?

MySQL组复制还是单个服务器就足够了?

该文档是否正确?(是/否对我来说足够了)

Password_hash和默认盐足够了吗?

NoValidHost:找不到有效的主机。没有足够的主机

Json Web令牌是否足够安全?以及如何确保有效载荷?

getResources()。getIdentifier()方法是否足够有效以在ListView中使用它?

WSL + samba + git:“错误:没有足够权限将对象添加到存储库数据库.git / objects” / git-clone / git-add权限错误

四舍五入并保留足够的有效数字以使其与邻居区分开

git clone在git shell中有效,但在Windows命令行中无效

git clone有效;git子模块失败“权限被拒绝”