2011-08-02 60 views
4

假設我有以下的基類:當構造函數在拋出異常之前部分成功時會發生什麼?

public class RootClass { 

    private List<RootClass> children = new ArrayList<RootClass>(); 

    public RootClass(RootClass parent) { 
    if (parent != null) { 
     parent.addChild(this); 
    } 
    } 

    public void addChild(RootClass child) { 
    children.add(child); 
    } 

} 

和我有以下子類:

public class ChildClass extends RootClass { 
    public ChildClass(RootClass parent) { 
    super(parent); 
    doInitialization(); 
    } 

    private void doInitialization() { 
    //Might throw an unchecked exception 
    } 
} 

現在,假設我創建一個ChildClass拋出異常的實例,但被捉住在構造函數之外(在代碼深處某處,如此遙遠,它不知道ChildClass尚未完全構建)。現在父母在其children列表中有一個參考,其中ChildClass沒有其構造函數運行。

這些情況應該如何處理?這只是一個糟糕的設計方案嗎?或者這是否有點意義?我不想重構整個應用程序,在構造函數完成後將子項添加到父項。

+0

可能的[關於Java中的構造函數]的副本(http://stackoverflow.com/questions/1371369/about-constructors-in-java) –

+1

「可能」重複的含義是什麼? – irreputable

+0

這種問題需要更多的投票 – Pacerier

回答

2

作爲一般原則,不惜一切代價避免從構造函數中泄漏'this'的值。在這種情況下,父對象將具有對半建對象的引用。它應該在呼叫者中被編碼爲例如parent.addChild(new Child())而不是自動添加add。

+0

我想知道是否有這種模式的有效用法。或者說,Java是否允許編譯這種代碼有一個原因? – Pacerier

+1

@Pacerier編譯器不會阻止你編寫不安全的代碼,只能阻止你編寫+不正確的代碼。 – EJP

+0

好吧,如果沒有這種類型的代碼的有效用例,它可能被認爲是「不正確」 – Pacerier

1

如果:

private List<RootClass> children = new ArrayList<RootClass>(); 

靜態字段,你只需有泄漏半初始化的對象到野外。事實並非如此,它沒有任何區別。

如果此引用泄漏到對象之外的某個位置,那麼您只有一個問題,那麼您將有一個半初始化對象等待導致系統出現問題。只要你確定參考資料本身不會出現任何問題,那就很好。

+0

不,他泄露它,導致父母,這是一個合法的,已經存在的實例,現在有一個引用的孩子。 –

相關問題