2012-05-18 22 views
3

如果構造函數以異常結束,是否創建的對象與普通構造函數完全相同?如果構造函數以異常結束,那麼創建的對象是否與正常創建的相同?

class A { 

    static A o; 

    A() throws Exception { 
     o=this; 
     throw new Exception(); 
    } 

    void f() { System.out.println("f(): entry."); }; 

    static public void main(String[]args) { 
     try { 
     A o =new A(); 
     } 
     catch (Exception e) { 
       System.out.println("Exception: " + e); 
     } 

     A.o.f(); // Is it safe to use this object? 
     } 
} 

這編譯和運行,而這個程序的輸出是:

Exception: java.lang.Exception 
f(): entry. 
+1

它是Java嗎?你甚至試過編譯它? – Sekhar

+1

是的,我做過。有用。 –

+1

@DonLi,user331225指出你錯過了一個'}',所以你的代碼示例不能編譯。 –

回答

3

如果您捕獲該異常發生什麼情況,構造的對象不會傳遞給調用者,調用者的結果變量沒有設置。但是,從理論上講,靜態變量會被設置,我看不到任何理由不能訪問。

但是請注意,在調用super構造函數之後,方法驗證將不允許您存儲this,因此這不是對其他受保護對象的「後門」。

既然是你的客體,那麼「安全」取決於你。

[更多細節:輸入構造函數的編譯版本時,「原始」Java對象被完全構建 - 系統無需額外工作即可使其生效。但是,super構造函數尚未被調用,因此您可以直接調用super調用或讓編譯器在默認情況下插入super調用(如果沒有調用,它將在方法開始時執行)一個明確的調用)。 JVM中的「字節碼驗證器」對調用super構造函數之前在構造函數中可能發生的情況有一些非常嚴格的規則,並且將this存儲到靜態將是一個明確的禁止 - 你會得到一個VerifyError。]

+0

謝謝。你是什​​麼意思「一個VerifyError」? –

+0

@DonLi - 加載類時的java.lang.VerifyError。 –

2
A.o.f(); // Is it safe to use this object? 

這是一個普通的Java對象,將到方法響應只是調用其他任何Java對象。就Java語言而言,這不是未定義行爲的來源。

這並不意味着它可以安全使用。許多班級的安全取決於他們維護重要不變量的能力,而且在施工或關鍵作業期間拋出的意外異常通常意味着這些不變量不能保持,因此不能安全使用。

考慮,如果你繼承一個

public class S extends A { 
    boolean dirty; 

    S() throws Exception { 
    // Do work to maintain important security invariants. 
    dirty = true; 
    } 

    void foo() { 
    if (dirty) { 
     System.out.println("clean"); 
     dirty = false; 
    } 
    System.out.println("foo"); 
    } 

    public static void main(String... argv) { 
    try { 
     new S(); 
    } catch (Exception ex) {} 
    // Now A.o is an instance of S, but S's constructor 
    // was never called. 
    S s = (S) A.o; // works. 
    s.foo(); // Never prints clean before printing foo. 
    } 
} 
+1

這個問題的關鍵在於構造函數異常返回(因此try語句中的賦值永遠不會看到結果),但仍然可以獲得對該對象的引用。你還沒有真正解決這個問題的實質性內容(你是第二段,我認爲這是OP的真正問題)。 –

+0

@GregKopff,定義「安全」取決於提問者,但即使提問者沒有提供我爲兩個常見定義回答的定義 - 它不是未定義行爲的來源,但是當不變性違反時是常見症狀已經發生了。 –

+0

我認爲Hot Licks在頭部受到攻擊是因爲除非superconstructor已經執行完成,否則不能使用'this'。用*那*信息,討論孩子班級的安全性更有意義。 –

相關問題