今天,我們將從兩個方面學習如何在java編程語言中創建新對象。
當java在壹個新的對象中時,它會先檢查對象所屬的類是否已經加載到內存中,如果沒有,它會先通過類的全限定名加載。
加載和初始化類完成後,將進行對象的創建。
讓我們假設類被使用壹次,這樣壹個對象就可以分為兩個過程:加載和初始化類和創建對象。
壹、類加載過程(使用這個類壹次)java使用父委托模型加載類,所以在描述類加載過程之前,我們先來看壹下它的工作過程:父委托模型的工作過程是:如果壹個類加載器收到壹個類加載請求,它不會嘗試自己加載這個類,而是將這個請求委托給父類加載器來完成。每壹級的類加載器都是如此,所以所有的加載請求最終都應該被發送到頂級的啟動類加載器。只有當父類加載器反饋無法完成這個加載請求時(在其搜索範圍內沒有找到需要加載的類),子類加載器才會嘗試自己加載。
使用父委托機制的好處是可以有效保證壹個類的全局性質。當程序中有多個具有相同限定名的類時,類裝入器在裝入時總是只裝入其中的壹個。
1.類加載器負責根據類的全限定名讀取類的二進制字節,存儲在運行時內存區的方法區,然後轉換成目標類型對應的java.lang.Class對象實例。2.驗證格式驗證:驗證是否符合類文件規範語義驗證:檢查標記為final的類型是否包含子類;檢查類中的最終方法是否被子類重寫;確保父類和子類之間沒有不兼容的方法聲明(比如方法簽名相同,但是方法的返回值不同)操作驗證:操作數棧中的數據必須正確操作,常量池中的各種符號引用都要驗證(通常在解析階段,通過符號引用中描述的全限定名檢查是否可以定位到指定類型上,類成員信息的訪問修飾符是否允許訪問等。) 3.準備為類中的所有靜態變量分配內存空間,並為它們設置壹個初始值(因為對象還沒有生成,實例變量不在此操作範圍內),final修改的靜態變量(常量)會直接賦值;4.將常量池中的符號引用解析成直接引用(在內存中獲取類或字段和方法的指針或偏移量以便直接調用方法),初始化後即可執行。
解析需要靜態綁定的內容。
//所有不會被重寫的方法和字段都將被靜態綁定。以上三個階段也稱為鏈接階段。鏈接階段需要做的是將加載到JVM中的二進制字節流的類數據信息合並到JVM的運行時狀態中。
5.初始化(父先於子)4.1給靜態變量賦值4.2執行靜態代碼塊註意:靜態代碼塊只能被jvm調用。如果壹個類需要被多個線程同時初始化,那麽只能允許壹個線程初始化它,其他線程必須等待。只有在活動線程完成初始化該類後,等待的其他線程才會得到通知。
因為子類依賴於父類,所以類的加載順序是先加載父類,再加載子類,初始化也是如此。
但是,當父類初始化時,子類的靜態變量的值也是默認值。
最後,方法區將存儲當前類的類信息,包括類靜態變量、類初始化代碼(定義靜態變量時的賦值語句和靜態初始化代碼塊)、實例變量定義、實例初始化代碼(定義實例變量時的賦值語句實例代碼塊和構造方法)和實例方法,以及父類的類信息引用。
2.創建對象1。在堆區域中分配對象所需的內存。分配的內存包括該類和父類的所有實例變量,但不包括任何靜態變量。2.為所有實例變量分配默認值,將方法區域中實例變量的定義復制到堆區域,然後分配默認值。3.執行實例初始化代碼的初始化順序是先初始化父類,再初始化子類。初始化時,首先執行實例代碼塊,然後執行構造方法。4.如果有Childc=newChild()形式的C引用,在堆棧區定義子類型引用變量C,然後將堆區對象的地址賦給它。需要註意的是,遼寧It培訓/發現每個子類對象都持有父類對象的引用,父類對象內部可以通過super關鍵字調用,外部不可訪問。