首先,什么是類的加載?類的加載由類加載器執行.該步驟將查找字節碼(classpath指定目錄),並從這些字節碼中創建一個Class對象。Java虛擬機為每種類型管理一個獨一無二的Class對象。也就是說,每個類(型)都有一個Class對象。一旦某個類的Class對象被載入到內存,他就被用來創建這個類的所有對象。
類的加載會發生在什么時候呢?所有的類都是在其第一次使用的時候,動態加載到JVM的。當程序創建第一個對類的靜態成員的引用時,就會加載這個類。構造方法默認也是靜態的,所以new的時候若該類未被加載,則也會進行加載操作。
另外說明下,有繼承體系的類也會被自動加載,不管該父類是否會被使用。比如B繼承了A。倘若任何類都未被加載,當 new B() 時,首先會將B加載了,隨后會將A給加載了。
對象的內存分配及初始化
- public class Demo_Student {
- public static void main(String[] args) {
- Student s = new Student();
- s.show();
- }
- }
- class Student {
- private String name = "張三";
- private int age = 23;
- public Student() {
- name = "李四";
- age = 24;
- }
- public void show() {
- System.out.println("我叫:"+name+",今年"+age+"歲");
- }
- }
1.首先,程序運行時,會將Demo_Student加載進內存,隨后,其主方法main入棧。緊接着發現了new Student(),所以又將Student加載進內存
字段信息:存放類中聲明的每一個字段的信息,包括字段的名、類型、修飾符。
方法信息:類中聲明的每一個方法的信息,包括方法名、返回值類型、參數類型、修飾符、異常、方法的字節碼。
2.然后在棧內存分配一塊空間(Student s),聲明Student的引用。new Studetn() 在堆內存開辟空間,進行默認初始化和顯示初始化
3.調用構造方法,系統默認調用。構造方法進棧,對對象進行初始化,初始化完成后,彈棧。此時對象已經創建完畢。將其地址值賦值給變量s
4.可通過s其地址值找到對應堆內存空間的實體,調用show方法時,show進棧,其內部有個隱藏的this引用,根據該引用找到堆內存實體,並打印相應內容
5.隨后main方法也執行完畢,彈棧,程序執行完畢
總結
Student s = new Student(); 在內存中到底執行了哪些步驟?
1,加載Sutdent.class文件進內存(類加載器)
2,在棧內存為 s 變量申請一個空間
3,在堆內存為Student對象申請空間
4,對類中的成員變量進行默認初始化
5,對類中的成員變量進行顯示初始化
6,有構造代碼塊就先執行構造代碼塊,如果沒有,則省略(此步上文未體現)
7,執行構造方法,通過構造方法對對對象數據進行初始化
8,堆內存中的數據初始化完畢,把內存值復制給 s 變量