[英]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.