JAVA-初步認識-第七章-this關鍵字記憶體配置圖解

來源:互聯網
上載者:User

標籤:失敗   name   控制台   classpath   接下來      區分   style   alt   

一.

對於靜態使用和注意事項已經講解過了,接下來用一個例子,把靜態所涉及的記憶體地區用圖的形式給大家展現一下。

 這裡面進行了一個Person的描述,裡面有兩個成員變數name,age,同時有一個靜態變數country。接下來Person當中給我們提供了一個建構函式,能同時初始化效能和年齡。接下來還有一個非靜態方法show,可以顯示出這個人的個人資訊。接下來還有一個靜態方法,它可以去顯示我們國籍。

主函數中我們先用類名的形式調用了靜態方法,緊接著建立了該類的對象,該類的對象調用了一個非靜態方法,這個方法只能被靜態調用。

上面的例子中,主函數裡面的語句Person p=new Person(); 這裡顯示括弧裡沒有任何參數。在描述類中,沒有空參數的建構函式,這裡也就無法進行建構函式初始化。

以上面的描述為例,來將記憶體中的過程展現一下。(我覺著這裡還是想將學到現在的所有物件導向知識點串起來,理清先後順序。)

上面的內容挺不同尋常的,沒有進行編譯StaticDemo2的來源程式,而是直接用java命令運行了StsticDemo2的類。就是說,沒有編譯就運行了?

這是在運行一個類,這個類就會被載入進記憶體,至於這個類被封裝對象的過程,現在講不了。這個部分到後面才能講到。一載入進來就要進行空間的開闢。

無論怎樣,電腦記憶體早就被劃分為幾個部分,來分別儲存不同的東西。目前涉及的記憶體地區主要有三個,棧,堆,方法區。

地區劃分完畢後,資料都在哪?是個問題。

方法存在哪?方法都存放在方法區裡。解析一下,方法是如何在方法區存放的。

當StaticDemo2這個類被執行的時候,其實這個類就進記憶體了(程式運行都是在記憶體中操作的)。這個類一進記憶體,就開闢空間了。

在方法區劃分了一片空間,儲存StaticDemo2的類,分完以後,這個類裡面有一個成員方法,就是StaticDemo2(),這個方法搞不清楚是哪來的?這個方法是這個類中的預設建構函式。會隨著類一起載入進來。

主函數是靜態,main()會被載入入靜態區,專門儲存靜態資料。靜態區裡也會標明是StaticDemo2的類,然后里面有static main()的方法。

上面一左一右,左邊是非靜態區,右邊是靜態區。非靜態區的方法和靜態區的方法都是被共用的。為什嗎?以描述類中的show()方法而言,所有的對象都具備這功能,唯一的不同是什嗎?就是對象所封裝的資料不一樣。有的對象叫張三,有的對象就李四,但是大家都會說話,都會說的自己姓名和年齡,所以這個功能是共用的,這個功能就在方法區裡面。只不過方法區分靜態和非靜態,因為調用方式和所屬的不一樣。非靜態地區裡面所有的成員都有一個this所屬。為什嗎?非靜態內容只能被對象調用。而到了靜態區,它有都有所屬的類名。

在控制台上,將java StaticDemo2一斷行符號,它就載入完了。載入完了,虛擬機器就直接使用這個類名,調用方法。這個時候,main方法就進棧。main方法進棧以後,它就要運行裡面內容,但是main方法裡面的代碼是儲存在靜態區。因為,來源程式中的所有東西都被轉換成了位元組碼檔案儲存體起來了。mian本身就在靜態區,它的代碼也在靜態區。

第一句Person.show()使用到了一個類,這個時候,這個類才載入。這個時候就去找,classpath路徑下是否有Person.class檔案。如果沒有設定classpath,它就預設在目前的目錄下找,找到以後,就會把person.class檔案載入進記憶體。一載入就會在方法區,分配空間了。Person類就進記憶體了,緊跟著Person的建構函式,以及show方法。它們載入完以後,static method的方法也會載入進來,這個方法所屬Person類。這是我們所說的靜態區,都是共用資料。緊接著,這裡面還沒完,裡面還有country,country預設初始化為null,接著初始化為"CN",

 

載入完以後,是Person.method(),是類名在調用。用類名調用,只能找靜態區。到靜態區一找,在Person這個類所屬的靜態區當中或者說在靜態區當中有Person類,Person類地區當中,有沒有main方法呢?有的話,method的方法就進棧了。這個方法持有this嗎?沒有,只有非靜態區的才有this。到目前為止,堆裡面沒有東西。注意,method的方法從方法區裡的靜態區,到了棧記憶體中。下面的右的虛線是代碼存放區,有的也叫做方法表。棧中的method是運行區,裡面會有局部變數,運行完釋放。棧區中存放方法的局部變數,System.out.println是不進來的,

 

方法進棧完以後,它就開始運行,啟動並執行時候,就開始執行方法行動代碼。有變數就開闢空間,沒變數空間開闢完以後就會釋放。一運行,Person.country就輸出了,它在調用country這個一個變數。發現這個變數是類名.,如果不寫類名.的話,class檔案裡也有。調用的時候,是找person裡靜態變數,一找到,就把CN給輸出了。輸出完以後,再往下就是return;method方法就彈棧了,到這呢,這個方法區就載入完畢了。

接著就執行第二句,Person p=new Person("java", 20); 接著主函數裡面就多了個p,=右邊是一個Person。堆記憶體中就開闢空間,分配地址編號,載入成員變數,預設初始化值。當然在類的描述當中,它可以描述描述自己的name和age,但是存在類型被使用,必須存到對象當中,因為這個name和age值是只能在對象中存在的。預設初始化完畢後,要接著建構函式初始化。這時,就要回頭找,相對應的建構函式。這個時候,建構函式就進棧了,而這個建構函式在訪問對象中的資料,它在給對象中的資料進行初始化。給哪個對象初始化呢?它不知道,所以它裡面就持有一個this,而這時正好是0x0056的對象在調用建構函式,所以this等於0x0056. 緊跟著它的name就被賦值為”java“,age就被賦值為”20“,。緊跟著,這個函數完事以後,開始執行,建構函式裡面的代碼,this.name=name, this.age=age,一致性時,發現建構函式裡面的name賦值給this.name,而this是0x0056的對象,也就是name=”java“賦值給了對象中的name。

  

這時候,建構函式就完畢了,它就要彈棧了。緊跟著,右邊堆中的對象初始化就結束了。接著就把地址編號0x0056賦值給左邊p,這樣一來,p就指向了對象。

最後,執行p.show(),調用show方法。在方法區的非靜態區有show方法。注意:在p.show在編譯的時候,它會檢查的源檔案是否有show,沒有的話,就編譯失敗了。可是啟動並執行時候,它也會檢查,發現有show,就讓show進棧。show是非靜態,show得有this所屬0x0056,執行裡面代碼,發現沒有局部變數,只有輸出語句。就直接執行輸出語句。在輸出的時候,發現輸出country,大家都知道在counrty在編譯完以後,在產生class檔案,就已經有類名所屬,所以它就找靜態區裡面的內容。找完以後,就列印了CN。接著找尋name和age的值,name和age前面有this,列印的都是0x0056的值,指向對象中的name和age值。找到以後,就輸出了,CN,java,20.輸出完以後,show方法就彈棧。

它彈棧以後,主函數的最後一句話就是return,這是預設,隱式,寫不寫都可以,系統會自動幫你加上,函數要結束。建構函式有return語句,一般方法有return語句。只有void的情況,return才可以省略。主函數有renturn,也彈棧。接著沒有代碼了,虛擬機器結束了。這裡面涉及線程。

 

JAVA-初步認識-第七章-this關鍵字記憶體配置圖解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.