簡體   English   中英

Stack Overflow java

[英]Stack Overflow java

作為類變量的對象會導致堆棧溢出

public class stack {
        stack obj = new stack();   // its obvious that during class loading obj will call class to
        // load and infinite loop will occur. 
}

假設我在類obj中使用static

public class stack {
      static stack obj = new stack();  // it will not cause infinite loop and program will //execute successfully
}

當JVM第一次捕獲類時,靜態變量被分配到內存中(據我所知)。 僅在JVM開始將內存分配給上述static對象變量時才說。 它會再次實際調用該類,這也應該導致無限循環。 在某個地方我錯了。 有人可以突出我錯在哪里。

不,將其聲明為static不會導致無限循環。 這就是原因。

靜態變量在類加載時間內初始化。 因此,當您的類第一次加載時,編譯器將為靜態變量創建一個實例,就是這樣。 這不會導致您的班級第二次加載。 由於您的課程沒有再次加載,因此不會重復此過程。

如果你將它聲明為非靜態屬性,那么這是一個完全不同的故事。 考慮一下 -

public class stack {
    stack obj = new stack();

    ........
}

該聲明相當於 -

public class stack {
   stack obj;

    public stack() {
        obj = new stack();    // implicitly moved here by the compiler
    }

    ........
}

從最后一個例子可以看出,為什么這里存在無限遞歸。 您正在其自己的構造函數中創建stack類的實例,該構造函數又創建另一個,然后另一個,......然后它繼續,導致堆棧溢出。

加載“stack”類將導致創建“stack”的實例,將其保存為堆棧類的靜態字段。 然后,堆棧類的這個實例無需加載:沒有堆棧異常。

關鍵字Static與無限循環無關。 你可以聲明字段,方法,類(靜態內部類)

靜態字段: -首次加載類時,會創建並初始化靜態字段。 當引用類的靜態成員或創建類的實例時(以先到者為准),就會發生這種情況。

靜態方法: -使用static關鍵字聲明的方法。 與靜態字段一樣,靜態方法與類本身相關聯,而不是與從類創建的任何特定對象相關聯。 因此,在使用類定義的靜態方法之前,不必從類創建對象。

最着名的靜態方法是main,由Java運行時調用以啟動應用程序。 main方法必須是static,這意味着默認情況下應用程序在靜態上下文中運行。

內存透視: -由於類被加載一次並且其定義存儲在jvm的permgen區域中,靜態變量也存儲在那里並且將在jvm的生命周期中存在。

當JVM第一次捕獲類時,靜態變量將分配給內存

不完全是。

加載類時會分配靜態變量。

初始化類時執行靜態變量初始化。 這可能發生在加載類之后的某個時間。

僅在JVM開始將內存分配給上述靜態對象變量時才說。 它會再次實際調用該類,這也應該導致無限循環。

不,這有兩個原因:

  • 通常,對象不是“實習”。 Interning是對String對象的操作,即使這樣,它也只對String文字自動發生。 如果應用程序在其上顯式調用String.intern()則非文字String對象只會被實現。

  • 即使自動執行某種實習,也不會導致無限循環。 您似乎認為實習會以某種方式導致類初始化重新啟動或重復。 這是不可能的,JVM需要相當長的時間才能確保每個類在其生命周期內最多初始化一次。

在調試期間,我們可以知道,當第一次控制到達靜態變量時,因為變量只是類的一個實例,它將調用類加載。

然后控件進入類,並找到一個靜態變量對象,但此時它將由JVM分配一個內存地址值(與其他靜態變量一樣)。 Control只是忽略變量作為實例,它純粹假定為靜態,程序繼續。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM