Java類與對象初始化的過程(一道經典的面試題)

來源:互聯網
上載者:User

標籤:static成員   idt   概念   進入   分享圖片   gpo   init   post   準備   

本文不再以ClassLoader的視角解釋這些問題。

首先,Java代碼有個特點,就是成員變數可以在前面的方法中使用,在後面定義。這一特性,很多人說Java了不起,可是為什麼呢?Java為何能夠這樣呢?

我們首先來看一道面試題: 

寫出上面代碼的運行結果。其實對於Java瞭解比較深入的人,不屑於解決這道題,因為看代碼寫運行結果,再常規不過,可是這個題,要是寫准了,還真的不容易,因為,我們要以類似C語言的視角審視這道題。OK,我們首先理解一個基本概念,記憶體空間一定是先申請,再初始化,再使用的。例如C語言中的malloc分配空間,然後初始化寫0,然後使用。其實Java也是如此的。首先,我們從main方法入手,只有一行new對象(第26行)。new對象首先要載入類,這是肯定的了,因此“Test”需要載入類,也就是載入Test的位元組碼檔案到方法區(永久代)中。這時需要把類中的“static”部分處理完成。也就是說,static部分是隨著Test的位元組碼檔案進入到永久代的。它的過程是:先把所有的static部分申請空間,然後再給每一個static成員由上至下分配初始值。初始值有兩種,一種是Java對於基礎資料型別 (Elementary Data Type)的預設初始值,這個預設初始值在申請空間之時就給每一個成員賦予了,另一種是Java程式員利用“=”對成員進行賦初始值。,五個靜態成員在永久代首先被分配記憶體。此時,k=0,t1=null,t2=null,i=0,n=0。空間申請完成之後,我們把0賦值給k,雖然k被分配記憶體之後就是0,但是依然還要把0再賦值給k,因為“=”右邊的“0”是程式員對k的賦值。然後是給t1執行個體一個對象,也就是t1原本是null,現在把new出來的對象賦值給t1,於是就要構建一個Test對象。構建對象時,要把所有的非static部分初始化一份,放入堆記憶體。這時,你就理解了Java文法中,為什麼靜態成員是“類名.成員”,而非靜態成員是“對象.成員”了。因為所屬關係不同。那麼我們開始找非靜態成員,有j和一個構造塊。因此是先給j申請空間,然後運行print("j")方法,把方法的傳回值交給j。於是,這個程式的第一段列印結果出來了:列印:此後,k=1 , n=1 , i=1。然後是接著找非靜態部分,就只有構造塊了,因此是:此後,k=2 , n=2 , i=2。這時,我們構造對象的準備工作做完了,也就是非靜態代碼都執行完了,因此開始執行個體化對象,Java執行個體化對象使用構造方法,因此執行:列印:此後,t1不再是null,然後初始化t2,過程和t1一樣,因此運行結果是:再然後初始化靜態i,因此是執行:輸出列印:然後初始化 n(第6行),直接把n賦值為99。但是什麼都不列印。然後再往下是靜態塊:輸出列印:至此,所有的靜態部分也都初始化完畢了,可以new Test("init")了:輸出列印:所以總體列印如下:總結,其實Java本身也是代碼從上往下走的,只不過靜態部分和非靜態部分在兩個次元裡。Java的成員有分配空間,賦預設值兩個過程,且首先為全體成員申請空間,然後由上至下逐一賦值。

Java類與對象初始化的過程(一道經典的面試題)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.