從零開始學Java【16】
阿新 • • 發佈:2022-05-07
從零開始學Java【15】
學習視訊:https://www.bilibili.com/video/BV12J41137hu?p=65
目錄建立物件記憶體分析
下面開始對上圖的程式進行分析:
- 首先程式對Application進行載入,把Application放到了堆裡面的方法區(注:方法區是在堆裡面的,是堆中其中一塊地方)裡面,此時Application有一個main方法,一個常量池,常量池用來存放字串,比如:“旺財”這個字串就是存放到裡面的。程式開始,main方法被放到棧的裡面,且為最底層的棧,這樣確保出棧的時候main是最後一個出來的。
- main方法開始執行,第一步程式執行Pet dog = new Pet(),此時程式是沒有Pet這個類的,於是程式就在方法區再生成一個Pet類,並且像載入Application那樣,開始加入屬性name,age還有方法shout,它也有常量池,但是"叫了一聲"這個字串是輸出語句,所以是不屬於常量池裡面的。此時有了Pet類,語句Pet dog = new Pet()就可以正常執行了。
3.執行Pet dog = new Pet(),通過new關鍵字開始呼叫構造器,因為是無參構造器然後name和age全都是預設值null和0
- 根據Pet類的模板,生成了dog物件,然後把dog物件放在了棧那裡,此時在棧裡面的dog只是一個引用變數名,引用的是堆裡面真正的物件,在堆這個物件裡面儲存了地址(假設為0x0001),name,age屬性值,以及shout方法,且shout方法呼叫的是方法區裡面的方法。此時,Pet dog = new Pet()這個命令已經走完。
dog.name = "旺財";
dog.age = 3;
dog.shout();
這三個命令已經走完
- 執行dog.name = "旺財",方法區裡面的Application常量池裡面的旺財,賦值給了堆裡面的name,於是堆裡面的dog物件更新屬性,同理,age也一樣,因為shout方法並沒有改變什麼,所以沒改。
- 同理,再建立一個cat物件也是一樣的道理。
- 此外,靜態方法區就是static關鍵字的地方,隨著類的載入而一起載入,所以堆裡面的物件可以隨時呼叫它。
總結
因為靜態方法是在方法區裡面,隨著類的載入而載入,靜態物件隨之產生;而非靜態方法是需要例項化物件才能呼叫的,所以非靜態的物件載入得比靜態慢,所以回憶上節的知識點:
非靜態可以呼叫非靜態和靜態
靜態可以呼叫靜態
唯獨靜態不可以呼叫非靜態
具體原理是:
- 靜態物件是和類一起載入的,所以靜態化的內容可以不用例項化就進行呼叫。
- 非靜態物件是類例項化之後才存在的。
可以看到,靜態的優先順序 > 非靜態,所以非靜態才可以一開始就呼叫靜態了,而呼叫非靜態則需要一定的條件(例項化)。
便可以結合起來理解了。
大總結(類與物件整個章節)
- 類是一個模板,是抽象的,物件是一個具體的例項的。
- 方法的定義和呼叫。這個需要掌握。
- 物件的引用。可以看到,非靜態物件是在棧裡面生成的引用變數名,然後這個引用指向堆裡面的實際物件。
- 物件的屬性,一般叫做成員變數。它一般都是預設初始化,比如null和0之類的。
預設初始化:
數字:0,0.0
char:u0000
boolean:false
引用:null
屬性的賦值:修飾符 屬性型別 屬性名 = 屬性值
- 物件的建立和使用
- 必須使用new關鍵字建立物件,且需要一個構造器。
- 呼叫物件的屬性。如 Pet dog = new Pet(); 再使用 dog.name就可以呼叫了
- 呼叫物件的方法 dog.shout();
- 類裡面,包含靜態的屬性和動態的行為,對應的即為屬性和方法,類裡面只有這兩種東西。