在使用控制面板時的實質:java
Hello.java
使用javac
,而後變成爲Hello.class
經過運行java
這個命令,在類加載器中(含有加載,驗證,準備,解析,初始化,使用,卸載),到jvm
爲Java虛擬機中運行,在jvm
中有方法區,堆內存,線程棧,本地方法棧,PC
計數器。jvm
類加載器:測試
class
文件的版本是否能兼容當前的Java
虛擬機版本,而後class
文件要知足虛擬機的規範。final
修飾的類變量除外,final
變量就直接初始化爲變量值,而類成員不同。xxx
,這種表明變爲直接引用,什麼是直接引用呢?就是內存地址,如咱們常見的xxx0203r0e
,這種。static
修飾的變量或者是static
靜態代碼塊按照順序組成構造器進行初始化變量。
JVM
spa
JVM:
方法區(保存全部類的信息,經過常量池來保存生成全部類信息的對象),堆內存,線程棧,本地方法棧,計數器。線程
// 在控制面板中,反編譯 javap -c xxx 就是將字節碼反編譯爲字節碼的指令輸出
public class Hello{ public Hello(); Code: 0: aload_0 1: invokespecial #1 4: return public static void main(java.lang.String[]); ... }
把程序放進jvm
中運行,到線程棧中運行,主方法main
(主線程),在線程棧中運行若是有遇到new
對象關鍵字時,main
這個主線程就會在本身的內存中(線程棧)聲明一個的對象(對象的引用指向堆內存中開闢的對象),Hello hello
;在jvm
中有個堆內存,就會申請一片空間內存地址,即建立一個對象,實例變量,實例方法從方法區中指向堆內存。code
public class Hello{ public static void main(String[] args){ Hello hello = new Hello(); // 對象的聲明 和 建立對象 } }
類加載到虛擬機中:對象
public class Demo static { System.out.println("靜態代碼塊"); } { System.out.println("普通代碼塊"); } public Demo(){ System.out.println("構造方法"); } public static void main(String[] args){ new Demo(); } } // 結果 靜態代碼塊 普通代碼塊 構造方法 // 加載 驗證 準備 解析 初始化 使用 卸載 Demo.java -> Demo.class -> 加載進入虛擬機中,類加載器 (驗證類信息,元素信息,版本,字節碼,準備,初始化類變量,解析把符號引用解析爲直接引用,進行初始化就是把static變量和static靜態代碼塊進行初始化變量)
步驟:blog
在堆內存中執行的順序就是加載實例信息,而後在進行構造方法。繼承
瞭解static案例內存
// 父類 public class F static { System.out.println("F靜態代碼塊"); } { System.out.println("F普通代碼塊"); } public F(){ System.out.println("F構造方法"); } } // 子類 public class S extends F static { System.out.println("S靜態代碼塊"); } { System.out.println("S普通代碼塊"); } public S(){ super(); // 默認的 System.out.println("S構造方法"); } } // 測試 public class Demo public static void main(String[] args){ // 建立子類對象 new S(); } } // 結果 F靜態代碼塊 S靜態代碼塊 F普通代碼塊 F構造方法 S普通代碼塊 S構造方法
程序進入JVM
中的方法區,子類繼承父類,父類進行加載實例信息進入到開闢的內存中,而後執行完再執行構造方法,在堆內存中new
一個對象,new S();
在子類的構造方法中會有默認的super()
,加載父類,若是子類調用默認調用super()
,而父類沒有無參的構造方法,而是有參的構造方法,那麼就要本身添加,在super(xxx)
中。