2015-10-09 96 views
2

請考慮以下代碼。Java中的對象初始化

public class Skyler { 
Skyler s1=new Skyler(); 
public static void main(String asd[]){ 
     Skyler s2=new Skyler(); 
    } 
} 

它產生java.lang.StackOverflowError異常。爲什麼?

也考慮下面的代碼。

public class Skyler { 
    Skyler s1=new Skyler(); 
    static Skyler s2=new Skyler(); 
    Skyler(){ 
     System.out.println("const"); 
    } 
    public static void main(String sdp[]){} 
} 

這也產生了相同的java.lang.StackOverflowError異常。爲什麼?

兩個例外情況的原因是否一樣?

回答

3

你經歷了一個循環,構造函數調用它自己的servaral時間直到它溢出。

對於前:

enter image description here

其原因是在兩種情況下相同。它無休止地稱它爲自我。

在您的這兩種情況下只有一次,你提供一個默認的無組織構造與打印語句,這樣你可以看到打印語句,直到你得到了錯誤差異。

+0

這是一個錯誤?這不是一個例外嗎? –

+0

@prateektomar號錯誤和異常之間有區別。 –

1

刪除Skyler s1=new Skyler();。用你的代碼,Skyler類有一個類型爲Skyler的變量,那麼它會一次又一次地創建一個Skyler,所以StackOverflowException存在。

2

每次創建的Skyler實例時,該實例的s1成員初始化,它創建的Skyler另一個實例,它初始化其他實例,它創建的Skyler等另一個實例的s1成員.. 。

換句話說,你有一個無限連接的調用Skyler構造函數,這導致StackOverflowErr

+0

這兩個代碼片段中的異常的原因是否相同? –

+0

@prateektomar是的。它是。在我的回答中添加了這個。請閱讀。 –

+0

@prateektomar是的。這兩個片段之間的唯一區別在於創建了第一個「Skyler」實例(第一個片段中的main方法和第二個片段中的靜態變量的初始化)。一旦發生,初始化'Skyler s1 = new Skyler();'會導致無限的構造函數調用導致異常。 – Eran

1

檢查邏輯,你創建一個新的Skyler,這是幹什麼的?它創建了一個新的Skyler,令人驚訝的是這個新的Skyler創建另一個新的Skyler。這一切都來自您的線Skyler s1=new Skyler();(不是靜態的),它會遞歸創建對象Skyler的endles實例。

1

Skyler類調用它自己的構造函數。因此,在創建Skyler實例的同時,還創建了另一個Skyler實例,等等......結果是一個StackOverflow。