Update 13. 谨慎地重写 clone 方法.md (#64)

This commit is contained in:
刘雄斌 2020-12-31 14:58:54 +08:00 committed by GitHub
parent af038f9073
commit 6007a0bba3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -172,7 +172,7 @@ Entry deepCopy() {
``` ```
  克隆复杂可变对象的最后一种方法是调用 super.clone将结果对象中的所有属性设置为其初始状态然后调用更高级别的方法来重新生成原始对象的状态。 以 HashTable 为例bucket 属性将被初始化为一个新的 bucket 数组,并且 put(key, value) 方法(未示出)被调用用于被克隆的哈希表中的键值映射。 这种方法通常产生一个简单,合理的优雅 clone 方法,其运行速度不如直接操纵克隆内部的方法快。 虽然这种方法是干净的,但它与整个 Cloneable 体系结构是对立的,因为它会盲目地重写构成体系结构基础的逐个属性对象复制。   克隆复杂可变对象的最后一种方法是调用 super.clone将结果对象中的所有属性设置为其初始状态然后调用更高级别的方法来重新生成原始对象的状态。 以 HashTable 为例bucket 属性将被初始化为一个新的 bucket 数组,并且 put(key, value) 方法(未示出)被调用用于被克隆的哈希表中的键值映射。 这种方法通常产生一个简单,合理的优雅 clone 方法,其运行速度不如直接操纵克隆内部的方法快。 虽然这种方法是干净的,但它与整个 Cloneable 体系结构是对立的,因为它会盲目地重写构成体系结构基础的逐个属性对象复制。
  与构造方法一样clone 方法绝对不可以在构建过程中,调用一个可以重写的方法(详见第 19 条)。如果 clone 方法调用一个在子类中重写的方法,则在子类有机会在克隆中修复它的状态之前执行该方法,很可能导致克隆和原始对象的损坏。因此,我们在前面讨论的 put(key, value) 方法应该时 final 或 private 修饰的。(如果时 private 修饰,那么大概是一个非 final 公共方法的辅助方法)。   与构造方法一样clone 方法绝对不可以在构建过程中,调用一个可以重写的方法(详见第 19 条)。如果 clone 方法调用一个在子类中重写的方法,则在子类有机会在克隆中修复它的状态之前执行该方法,很可能导致克隆和原始对象的损坏。因此,我们在前面讨论的 put(key, value) 方法应该是 final 或 private 修饰的。(如果是 private 修饰,那么大概是一个非 final 公共方法的辅助方法)。
  Object 类的 clone 方法被声明为抛出 CloneNotSupportedException 异常,但重写方法时不需要。 公共 clone 方法应该省略 throws 子句,因为不抛出检查时异常的方法更容易使用(详见第 71 条)。   Object 类的 clone 方法被声明为抛出 CloneNotSupportedException 异常,但重写方法时不需要。 公共 clone 方法应该省略 throws 子句,因为不抛出检查时异常的方法更容易使用(详见第 71 条)。