簡體   English   中英

使用new關鍵字和副本構造函數而不是super.clone()的Java clone()方法

[英]Java clone() method using new keyword and a copy constructor instead of super.clone()

在網上尋找如何多態復制對象的深層副本時,我找到了一種解決方案 ,聲稱可以解決clone()方法的許多問題,例如無法克隆final字段。 該解決方案在clone()實現中結合了受保護的副本構造函數的使用,並且基本上是這樣的(示例是從引用的頁面復制的):

public class Person implements Cloneable
{
    private final Brain brain; // brain is final since I do not want 
                               // any transplant on it once created!
    private int age;

    public Person(Brain aBrain, int theAge)
    {
        brain = aBrain; 
        age = theAge;
    }

    protected Person(Person another)
    {
        Brain refBrain = null;
        try
        {
            refBrain = (Brain) another.brain.clone();
            // You can set the brain in the constructor
        }
        catch(CloneNotSupportedException e) {}
        brain = refBrain;
        age = another.age;
    }

    public Object clone()
    {
        return new Person(this);
    }

    …
}

Brainclone()方法可以類似的方式實現。

根據clone()方法文檔 ,似乎此方法的所有“合同”都不是絕對要求,並且“返回的對象應通過調用super.clone() ”只是一個約定。

那么,此實現實際上不正確嗎? 為什么?

如果正確,為什么它沒有成為設計模式? 這有什么缺點???

謝謝,彼得

您正在嘗試通過實現可克隆的接口來克隆,但不遵循建議的克隆協議。

您基本上是在使用復制構造函數創建新對象,那么我的問題是為什么您需要實現可克隆的?

如果要實現可克隆,則必須遵守合同。 當您在克隆方法中使用復制構造函數時,我將不推薦這種方法,因為它的子類的克隆將不是子類的對象,而代替將是Person類的對象。

還想指出的是,使用拷貝構造函數代替可克隆接口是更面向對象的方法。

那么,此實現實際上不正確嗎? 為什么?

這是不安全的,因為刪除了CloneNotSupportedException。

如果大腦不是可克隆的,那么新的人將沒有大腦:)如果您的對象結構中有一個不受控制的對象(無法訪問源代碼)怎么辦?

為什么它沒有成為設計模式

因為並非所有對象都只能從相似對象中克隆。 通常,有些環境對象比該對象的現有鄰居對象更了解該特定新對象的外觀。

該方法的缺點(除了刪除CloneNotSupportedException的事實之外)是,如果子類調用super.clone()它們將獲得Person的實例,而不是他們自己期望的類的實例。

如果您知道子類將不依賴Object.clone() (或者如果沒有子類),則方法是可以的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM