2017-06-17 32 views
-2
class ABC { 
    int x; 
    static ABC y = new ABC(); 
} 


public class XYZ { 

    public static void main(String[] args) { 
     ABC q = new ABC(); 
     q.x = 5; 
     System.out.println(q.x); 
    } 

} 

有人可以解釋代碼運行時發生的一切(一步一步)嗎?擁有自己類型的靜態成員的類

此外,當static關鍵字被刪除之前,實例y,StackOverflow發生錯誤。爲什麼在static關鍵字存在時不會發生這種情況?

在此先感謝。

+0

是你的家庭作業,你不明白這個代碼準確嗎? –

+2

如果你刪除了'static',那麼每個'ABC'實例都有它自己的'y'字段,這意味着對於每個創建的ABC實例,''y'值需要一個新的'ABC'實例,所以它會創建一個新的'ABC'實例,它需要一個新的'y'值,因此它會創建一個新的'ABC'實例,它需要一個新的'y'值,因此它會創建一個新的ABC實例,新的'y'值,所以它創建一個新的ABC實例,它需要一個新的'y'值,所以它創建一個新的ABC實例,它需要一個新的'y'值,StackOverflowError! – Andreas

+1

這就像試圖不正確地使用SingleTon模式:p – WilomGfx

回答

1

static表示變量的單個實例在多個引用對象中使用(在本例中爲y)。

A static該字段位於class的上下文中,這意味着該類的所有實例都將指向相同的static對象實例。 在一個場景:

ABC a = new ABC(); 
ABC b = new ABC(); 
System.out.println(a.y==b.y); 

打印將導致true,因爲y兩個ab指向同一個對象實例。

非靜態字段會填充繼承自己的單個實例;這意味着在一個情形:

ABC a = new ABC(); 
ABC b = new ABC(); 
System.out.println(a.y==b.y); 

(在一個假設的情況,其中,例如將不會觸發的StackOverflow)將導致false,因爲a.y相同實例作爲b.y;每個人在其y字段中都有自己的獨立實例ABC

因爲當ABC實例化時,需要另一個ABC實例是y場,其中,實例化時,創建另一個ABC,依此類推,無限(直到堆棧溢出)一個StackOverflow會發生不static關鍵字。

隨着static,ABC的一個靜態實例,讓我們把它創建sABC,以及它自己的y場只是引用它本身,所以實例化的無限循環不會發生。

+0

感謝您的幫助。你能告訴我,對象'q'看起來會是什麼樣子。我的意思是它有對象'y'或只有整數'x'? –

+0

「ABC」的所有實例都有一個「y」字段。不同之處在於'y'對象指向的內容。在'q'(你在你的main中創建的實例)中,它指向'y'(一個靜態的,第二個實例,它在實例化時被實例化,因爲'static ABC y = new ABC();'定義ABC類是什麼。)...在'y'(實例)中,'y'(字段)指向'y'(實例)本身。如果'y'不是靜態的,'y'實例會用一個新的實例填充它的'y'字段,這需要另一個實例來存放它自己的內部'y'字段,這需要一個用於它的'y'字段,所以在... – XenoRo

+0

@AayushTaneja我編輯了答案,試圖讓事情更清晰。如果您仍然不明白,我強烈建議(重新)閱讀OOP的基礎知識。 – XenoRo

0

當類加載器加載此類時,它將立即創建該類的一個實例並將其分配給類變量y。這是因爲y被聲明爲靜態的。 如果你沒有聲明y靜態,那麼你認爲ABC類的每個實例都有一個屬性y,它也是一個ABC。然後你也會說y屬性必須分配一個ABC類的新實例,所以無論何時顯式創建一個ABC實例,都會爲您創建該實例,就像您在main()中的第一個語句中那樣。你發現遞歸?這導致堆棧溢出。

+0

謝謝你的幫助。 –

0

靜態變量是一個類級變量。

實例變量是對象級變量。

如果刪除static關鍵字 - 此類嘗試實例化自身併發生無盡循環,而靜態變量一次創建一個實例並在所有對象之間共享。

堆棧內存保留局部變量和函數調用,所以它溢出了,因爲你有無盡的呼叫。

+0

感謝您的幫助。 –

0

的演練

ABC q = new ABC(); 

創建一個名爲q

q.x = 5; 

設置q的財產xABC類的新實例5

System.out.println(q.x); 

小學nt下通過q的屬性x保持的值(應爲5)

靜態

static關鍵字意味着一個類共享同一個變量的每個實例。當您創建類ABC的實例時,它將包含另一個ABC實例作爲變量y。當您創建另一個ABC實例時,它也有一個變量y,但該變量與ABC的第一個實例持有的y相同。

如果您要刪除static關鍵字,則y將不會由ABC的每個實例共享。當您創建ABC的實例時,它將創建它自己的y,並且該y將創建它自己的y,依此類推,直到您用完內存並且發生StackOverflow錯誤。

+0

謝謝你的幫助。 –