2014-06-10 91 views
0

Oracle的文檔說,有三個部分來創建對象 (聲明,實例化和初始化)。它也意味着它們「按順序排列」,但它沒有明確地說明這一點(雖然這通常似乎是正確的)。Java中的遞歸理論

所以,我想知道如果, 基於這樣的事實,在我的例子中,不正確編碼的構造將導致遞歸, 是否有可能在這種情況下(有關於事件的序列)試圖 到實例化對象首先發生,並且(在這種情況下)由於 遞歸,對象引用聲明從不發生....?

public Test(){ 
Test t1 = new Test(); 

}

+0

不,總是首先發生聲明 –

+1

任何語言的遞歸理論:遞歸是goofball的第一選擇,也是絕望而又勝任的程序員的最後選擇。 – DwB

+2

@DwB,遞歸是一種優雅,緊湊的方式來描述一些計算。如果優雅,緊湊的源代碼沒有價值,那麼我們仍然會用匯編編寫。對於許多問題,遞歸也恰好是_practical_。如果不是,那麼沒有人會使用它。另外,一個好的編譯器知道如何將尾遞歸轉換爲迭代函數。是的,有些情況下它是一個壞主意,但在所有情況下都不是這樣。 –

回答

1

宣言永遠是第一位的,其實它可以在方法,無論你在哪裏首先要提及一個變量(因爲它們是在一次創建)

失敗實例的開始發生,可能會導致intialisation不發生。

如果構造函數沒有正常退出(這裏您將得到一個StackOverflowError)聲明的字段或變量將不會被設置,而是會拋出一個錯誤。

在上面的例子中,t1不會在任何點設置。

「賦值運算符是從右向左讀的......」

它可能會以爲

Test t1 = new Test(); 

Test t1; 
t1 = new Test(); 
+0

Ahhhh。這是我尋找的理由!然後,就事件而言,遞歸(如果存在)確實發生在對象聲明之後。可能聽起來像是一件容易的事,但是讓問題開始的原因是「一個賦值操作符是從右到左讀的......」。我認爲我正在讀得太深。這很有幫助。 – Michael

+0

@vee添加了可能有所幫助的說明。 –

2
public Test(){ 
Test t1 = new Test(); 

} 

Test類的新實例將繼續創建,直到所有堆棧空間已用盡,你JVM將關閉給堆棧溢出錯誤。

+0

實例是否會完全創建? –

0

,這是很有幫助很容易嘗試自己。嘗試一下並記下結果。

public Test() 
{ 
    Test t1 = new Test(); 
} 

public static void main(String[] args) 
{ 
    Test t = new Test(); 
} 
+1

感謝您的測試 – Michael

0

您需要以聲明類Test的實例爲您遞歸擺在首位踢出。但是,對象的實例化從不返回,所以聲明從不成功。

-1

是的。它是遞歸的並且會溢出堆棧。最好的測試方法是使用調試器。

0

這裏有一個無限遞歸的例子,因爲沒有什麼可以讓我們退出遞歸循環。正如其他人之前所說的那樣,這將導致堆棧溢出錯誤,因爲JVM將持續創建內存分配並將其分配給Test對象,直到內存空間用完。