你好,我想问下java中对象的初始化过程具体指什么,是怎样进行初始化的
PHPz
PHPz 2017-04-18 10:35:57
0
5
414
PHPz
PHPz

学习是最好的投资!

全部回覆(5)
小葫芦
public class A {
    A a = new A();
    public static void main(String[] args) {
        A a = new A();
    }
}

上面這段程式碼編譯成字節碼在翻譯回來就像下面這樣:

public class A {
    public A(){
        A a = new A();//这里重复调用了自己
    }
    public static void main(String[] args) {
        A a = new A();
    }
}
大家讲道理

最簡單的回答應該是每次new A()時都會建立一個物件。

下面分析一下稍微詳細一點的過程
1.程式執行後首先進入main函數,然後第一次執行main函数,然后第一次执行new A();
2.由於沒有顯示的構造函數,編譯器在編譯的時候會產生一個無參構造函數

 public A(){
 }

3.進入上面的建構子後先要初始化成員變量,也就是 A a = new A(); A a = new A();
4.这里就到的问题的关键,成员变量A初始化还是new A()继续调用2中的构造函数。
5.接着就会重复2、3、4的步骤,直到这个线程的栈空间不够用,抛出StackOverflowError4.這裡就到的問題的關鍵,成員變數A初始化還是

繼續呼叫2中的建構子。

5.接著就會重複2、3、4的步驟,直到這個執行緒的堆疊空間不夠用,拋出JVM中,每个线程都会分配一定的栈空间(非共享),这个栈空间可以是固定的可以是动态扩展的,不同的JVM錯誤。

這裡還要普及一點方法呼叫的知識,在StackOverflowError這裡的實作方式可以不同。線程中每執行一個方法,這個方法就會以堆疊幀的形式壓入線程棧中。

🎜上面出現🎜就是因為一直不斷的呼叫建構方法,然後一直創建棧幀壓入線程棧,最後棧空間不夠用,導致棧溢位。 🎜
PHPzhong

變數的初始化和記憶體中的運作機制

成員變數的初始化和記憶體中的運作機制

當系統載入類別或建立該類別的實例時,系統會自動為成員變數分配記憶體空間,並在分配記憶體空間後,自動為成員變數指定初始值。

局部變數的初始化和記憶體中的運作機制

局部變數定義後,必須經過明確初始化後才能使用,系統不會為局部變數執行初始化。這意味著定義局部變數後,系統並未為這個變數分配記憶體空間,直到等到程式為這個變數賦初始值時,系統才會為局部變數分配內存,並將初始值儲存到這塊記憶體中。

正確的程式碼

public class A 
{
    public static void main(String[] args) 
    {
        A a = new A();
    }
}

java.lang.StackOverflowError異常

java.lang.StackOverflowError就是記憶體溢出,出現死循環;題主不應該在A類裡創建A類的實例,A()相當於一個無參構造器,在A類裡直接寫A a = new A ();會導致無限迭代地建立實例,最後導致記憶體溢位;錯誤提示也寫明程式在第4行處出現錯誤,而且反覆循環地出現錯誤

知識補充

歡迎題主來我主頁學習Java知識並交流指導,關於題主所提及的知識點在我主頁的Java面向對象(上)有提及:https://segmentfault.com/a/11.. .

洪涛

樓上兩位已經解釋的很清楚了,簡單的說就是你為類A增加了一個自身的實例變量a,這本身沒什麼問題,但是你將a的初始化放在了實例初始化的過程中,這樣的話只要呼叫一次new A()就會進去一個無限呼叫的循環,所以就堆疊溢位了。

黄舟

非常明顯的遞歸調用,而且沒有結束條件,肯定就內存溢出。遞迴就是方法裡呼叫方法本身,而你給的案例特別一點,是構造方法,原因就是這麼簡單。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板