首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 類生命週期全景解析:從載入到卸載的七大階段

     編輯:Java 程式設計入門

生命週期三大階段

┌─────────────────────────────────────────────────────────────┐
│ 1. 啟動階段 (類載入過程)                                       │
│    載入 → 驗證 → 準備 → 解析 → 初始化                          │
├─────────────────────────────────────────────────────────────┤
│ 2. 使用階段 (對象實例化與 GC)                                  │
│    實例化 → 使用 → 垃圾收集 → 終結                            │
├─────────────────────────────────────────────────────────────┤
│ 3. 結束階段 (類卸載)                                           │
│    類卸載 (僅用戶類加載器載入的類)                             │
└─────────────────────────────────────────────────────────────┘

階段一:類載入 (Loading → Initialization)

1. 載入

  • 通過全限定名獲取二進制字節流 (文件、網路、JAR、動態生成)
  • 將字節流轉為方法區運行時數據結構
  • 在堆中創建 java.lang.Class 實例作為訪問入口

2. 驗證

  • 文件格式驗證 (魔數、版本、常量池)
  • 元數據驗證 (語義分析:父類存在、final 不被繼承、靜態方法不覆寫...)
  • 字節碼驗證 (數據流/控制流分析:棧溢出、類型匹配、跳轉合法)
  • 符號引用驗證 (解析階段:類/字段/方法是否存在、訪問權限)

3. 準備

  • 為 靜態字段 分配內存並設置默認值 (0、null、false)
  • 不包含實例字段 (實例字段在對象實例化時分配)
  • static final 編譯期常量值在準備階段直接賦值

4. 解析

  • 將常量池符號引用轉為直接引用 (指針/偏移量)
  • 涉及:類/介面、字段、方法、方法類型、方法句柄、調用點限定符
  • 可延遲到首次使用時執行 (JVM 選項控制)

5. 初始化 <clinit>()

  • 執行類構造器:靜態字段顯式賦值 + 靜態代碼塊,按源碼順序
  • 父類 <clinit> 先於子類執行 (接口除外,接口初始化不要求父接口先初始化)
  • 多線程並發初始化時,JVM 加鎖保證只執行一次

六大主動使用觸發初始化 (JLS 強制規定)

  1. new、反射、克隆、反序列化創建實例
  2. 調用類的 靜態方法
  3. 訪問/賦值類的 非常量靜態字段 (final 編譯期常量除外)
  4. 反射調用 Class.forName、Method.invoke 等特定 API
  5. 初始化子類 (觸發父類初始化)
  6. JVM 啟動指定的主類 (public static void main)

被動使用 (訪問父類靜態字段、定義數組、訪問常量) 不會 觸發初始化。

階段二:對象實例化

四種顯式實例化途徑

  1. new 操作符
  2. Class.newInstance() / Constructor.newInstance() (反射)
  3. Object.clone()
  4. ObjectInputStream.readObject() (反序列化)

四種隱式實例化

  1. 命令行參數 String[]
  2. 類載入時隱式創建 Class 對象
  3. 常量池字面量創建 String 對象
  4. 字符串連接 + 生成 StringBuilder/String

實例化三步驟

  1. 堆中分配內存 (指針碰撸/TLAB)
  2. 實例字段賦默認值
  3. 執行 <init>() (構造器):按聲明順序賦顯式值 → 執行構造器代碼

階段三:垃圾收集與終結

  • JVM 必須提供自動堆管理 (垃圾收集器)
  • 對象聲明 void finalize(),GC 釋放內存前調用
  • finalize() 拋出的異常被忽略,不保證執行順序/時間
  • 不推薦依賴 finalize,資源釋放用 try-with-resources / Cleaner / PhantomReference

階段四:類卸載

  • 啟動類加載器載入的類 永不卸載 (贏在起跑線)
  • 用戶自定義類加載器載入的類,當類加載器不可達、類無實例、Class 對象不可達 時可被卸載
  • 熱部署、OSGi、Tomcat 熱加載本質:銷毀舊類加載器 → 類卸載 → 新類加載器載入新版本
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved