【從零學習JVM|第三篇】類的生命周期(高頻面試題)

前言:

在Java編程中,類的生命周期是指類從被加載到內存中開始,到被卸載出內存為止的整個過程。了解類的生命周期對于理解Java程序的運行機制以及性能優化非常重要。本文會深入探尋類的生命周期,讓讀者對此有深刻印象。

目錄

?編輯前言:

類的生命周期

類的加載階段

核心任務

連接階段

?驗證(Verification)

?準備(Preparation)

解析(Resolution)

初始化階段

()?方法特性

不會導致初始化

初始化觸發條件(嚴格規定)

使用階段

卸載階段

面試題

總結


類的生命周期

一個類的生命周期分為五個階段,分別是加載,連接,初始化,使用和卸載。

類的加載階段

加載是將類的字節碼文件(.class)加載到 JVM 內存的過程,類加載器會通過不同的形式,去得到字節碼文件的內容,然后通過JVM,把內容加載到方法區和堆區,而我們開發者只能訪問到堆區的內容,方法區我們是訪問不到的,堆區的內容是字節碼文件的核心內容。

核心任務

  1. 查找字節碼

    • 通過類的全限定名查找字節碼文件

    • 搜索路徑:類路徑(classpath)、JAR 文件、網絡資源等

  2. 創建類結構

    • 解析字節碼并創建對應的類數據結構

    • 在方法區(元空間)存儲類的運行時常量池、字段和方法信息

  3. 創建 Class 對象

    • 在堆內存中創建 java.lang.Class 對象

    • 該對象作為訪問類元數據的入口

連接階段

在加載階段結束后進入連接階段,連接階段分為三個子階段,確保類字節碼的正確性和可用性

?驗證(Verification)

確保字節碼符合 JVM 規范和安全要求:

  • 文件格式驗證:魔數(0xCAFEBABE)、版本號等

  • 元數據驗證:語義檢查(是否有父類、final類是否被繼承等)

  • 字節碼驗證:數據流和控制流分析

  • 符號引用驗證:檢查引用的類、字段和方法是否存在

?準備(Preparation)

為類變量分配內存并設置初始值:

  • 靜態變量分配

    • 在方法區分配內存

    • 設置類型默認值(零值)

      • int → 0

      • boolean → false

      • 引用類型 → null

  • 特殊處理

    • static final 常量:直接賦程序指定值

// 準備階段直接賦值
public static final int MAX = 100;

解析(Resolution)

將符號引用轉換為直接引用:

  • 符號引用:用一組符號描述引用的目標

  • 直接引用:指向目標的指針、偏移量或句柄

初始化階段

執行靜態代碼塊的內容和給靜態變量賦值,以字節碼文件視角就是執行<clinit>方法

<clinit>()?方法特性

  1. 自動生成

    • 編譯器收集所有類變量賦值靜態代碼塊

    • 按源代碼順序合并生成

  2. 線程安全

    • JVM 保證只有一個線程執行初始化

    • 其他線程會阻塞等待完成

  3. 父類優先

    • 執行子類的?<clinit>()?前

    • 必須先執行父類的?<clinit>()

不會導致初始化

  1. 無靜態代碼塊且無靜態變量賦值語句。
  2. 有靜態變量的聲明,但是沒有賦值語句。
  3. 靜態變量的定義使用final關鍵字,這類變量會在準備階段直接初始化?。
  4. 直接訪問父類的靜態變量,不會觸發子類的初始化。
  5. 數組的創建不會導致數組中元素的類進行初始化。

初始化觸發條件(嚴格規定)

  1. new?實例化對象

  2. 訪問類的靜態變量(非 final 常量)

  3. 調用類的靜態方法

  4. 反射調用(Class.forName())

  5. 初始化子類時(父類需先初始化)

  6. JVM 啟動時的主類

  7. MethodHandle 解析結果涉及靜態方法

使用階段

類的初始化之后,它就可以在程序中自由使用了。這包括創建實例、調用方法和訪問字段等操作。在這個階段,對象會被創建和操作,它們各自也會經歷自己的生命周期。

卸載階段

?在某些情況下,當一個類不再需要時,它會被卸載。類的卸載發生在垃圾收集的過程中,當確定某個類的Class對象不再被引用,且對應的ClassLoader實例也不再存在時,JVM就可能卸載這個類。但是,在常見的Java應用中,由于系統類加載器加載的類一直會被引用,所以這些類通常只有在JVM停止運行時才會被卸載。

面試題

說出一下代碼的運行結果:

public class Demo01 {public static void main(String[] args) {System.out.println(B02.a);}
}
class A02
{static int a=0;static{System.out.println("A02");a=1;}
}
class B02 extends A02{static{System.out.println("B02");a=2;}
}

運行結果為A02 1? 原因是因為:訪問父類的靜態變量,只初始化父類

public class Demo01 {public static void main(String[] args) {new B02();System.out.println(B02.a);}
}
class A02
{static int a=0;static{System.out.println("A02");a=1;}
}
class B02 extends A02{static{System.out.println("B02");a=2;}
}

首先執行main方法,new了B02所以要初始化它,但是它是子類,所以要先初始化A02,首先給賦值為0然后打印出A02,在給a賦值1,在初始化B02,打印出B02,a賦值為2,然后打印出a的值2

運行結果是:A02 B02 2

public class test5 {public static void main(String[] args) {System.out.println("A");new test5();new test5();}public  test5(){System.out.println("B");}{System.out.println("C");}static {System.out.println("D");}}
  1. 先執行test5這個類的靜態代碼塊輸出D
  2. 在執行main方法打印A
  3. 在初始化test5,執行構造器方法和代碼塊方法,但是代碼塊先執行所以第一個new執行CB
  4. 第二個new執行CB
  5. 結果:DACBCB

以上面試題你都做對了嗎?

總結

? ? Java類的生命周期包括:加載(將字節碼加載到內存,生成Class對象)、連接(驗證字節碼、準備靜態變量內存并賦默認值、解析符號引用)、初始化(執行靜態代碼塊和賦值)、使用(創建實例、調用方法)、卸載(類不再使用時被回收)。按此順序完成從加載到銷毀的完整過程。

學習類的生命周期,能讓我們對java語言有一個更深的認識,也能讓我們在面試中多一點機會。

總之,類的生命周期從加載到卸載,經歷了多個階段,每個階段都有特定的任務和目標。理解類的生命周期有助于我們更好地理解和管理Java程序的運行機制。

感謝你的閱讀,希望文章能給你帶來幫助,你的閱讀點贊就是我最大的動力。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83173.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83173.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83173.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Significant Location Change

一、Significant Location Change是什么 “Significant Location Change&#xff08;重大位置變化&#xff09;” 是蘋果 iOS 系統中一項用于在應用未主動運行時&#xff0c;監測設備位置顯著變化的功能。它主要通過基站、Wi-Fi 網絡等信號來判斷設備是否發生了有意義的位置移…

ubuntu22.04有線網絡無法連接,圖標也沒了

今天突然無法有線網絡無法連接任何設備&#xff0c;并且圖標都沒了 錯誤案例 往上一頓搜索&#xff0c;試了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角網絡圖標消失 最后解決的辦法 下載網卡驅動&#xff0c;重新安裝 操作步驟 查看自己網卡的型號 lspci | gre…

基于cnn的通用圖像分類項目

背景 項目上需要做一個圖像分類的工程。本人希望這么一個工程可以幫助學習ai的新同學快速把代碼跑起來&#xff0c;快速將自己的數據集投入到實戰中&#xff01; 代碼倉庫地址&#xff1a;imageClassifier: 圖片分類器 代碼切到master分支&#xff0c;master分支是本地訓練圖…

【HarmonyOS 5 開發速記】如何獲取用戶信息(頭像/昵稱/手機號)

1.獲取 authorizationCode&#xff1a; 2.利用 authorizationCode 獲取 accessToken&#xff1a;文檔中心 3.獲取手機&#xff1a;文檔中心 4.獲取昵稱頭像&#xff1a;文檔中心 首先創建 request 若要獲取手機號&#xff0c;scope必填 phone&#xff0c;permissions 必填 …

從OCR到Document Parsing,AI時代的非結構化數據處理發生了什么改變?

智能文檔處理&#xff1a;非結構化數據提出的挑戰 在這個時代的每一天&#xff0c;無論是個人處理賬單&#xff0c;還是企業處理合同、保險單、發票、報告或成堆的簡歷&#xff0c;我們都深陷在海量的非結構化數據之中。這類數據不像整齊排列的數據庫表格那樣規整&#xff0c;…

Python Ovito統計金剛石結構數量

大家好,我是小馬老師。 本文介紹python ovito方法統計金剛石結構的方法。 Ovito Identify diamond structure命令可以識別和統計金剛石結構,但是無法直接輸出結構的變化情況。 本文使用python調用ovito包的方法,可以持續統計各步的金剛石結構,具體代碼如下: from ovito…

相關類相關的可視化圖像總結

目錄 一、散點圖 二、氣泡圖 三、相關圖 四、熱力圖 五、二維密度圖 六、多模態二維密度圖 七、雷達圖 八、桑基圖 九、總結 一、散點圖 特點 通過點的位置展示兩個連續變量之間的關系&#xff0c;可直觀判斷線性相關、非線性相關或無相關關系&#xff0c;點的分布密…

Git常用命令完全指南:從入門到精通

Git常用命令完全指南&#xff1a;從入門到精通 一、基礎配置命令 1. 用戶信息配置 # 設置全局用戶名 git config --global user.name "你的名字"# 設置全局郵箱 git config --global user.email "你的郵箱example.com"# 查看所有配置 git config --list…

為什么要創建 Vue 實例

核心原因:Vue 需要一個「控制中心」來驅動整個應用 你可以把 Vue 實例想象成你應用的**「大腦」或「引擎」。它負責協調模板、數據、邏輯和行為,將它們變成一個活的、可交互的應用**。沒有這個實例,你的代碼只是一堆靜態的 HTML、JavaScript 變量和函數,無法「活」起來。 …

正則持續學習呀

源匹配為 (.*): (.*)$ 替換匹配為 "$1": "$2", 可將headers改為字典 參考 【爬蟲軍火庫】如何優雅地復制請求頭 - 知乎

python --導出數據庫表結構(pymysql)

import pymysql from pymysql.cursors import DictCursor from typing import Optional, Dict, List, Anyclass DBSchemaExporter:"""MySQL數據庫表結構導出工具&#xff0c;支持提取表和字段注釋使用示例:>>> exporter DBSchemaExporter("local…

Kafka 消息模式實戰:從簡單隊列到流處理(二)

四、Kafka 流處理實戰 4.1 Kafka Streams 簡介 Kafka Streams 是 Kafka 提供的流處理庫&#xff0c;它為開發者提供了一套簡潔而強大的 API&#xff0c;用于構建實時流處理應用程序。Kafka Streams 基于 Kafka 的高吞吐量、分布式和容錯特性&#xff0c;能夠處理大規模的實時…

VAS1086Q 奇力科技線性芯片車規用品LED驅動芯片

一、產品概述 名稱與定位&#xff1a;VAS1086Q 是奇力科技&#xff08;Chiplead Technology&#xff09;推出的汽車級恒流 LED 驅動器&#xff0c;屬于 Value Added Solutions 系列&#xff0c;專為汽車 LED 照明應用提供高性價比方案。 核心功能&#xff1a; 支持 10~400mA 可…

適應性Java用于現代 API:REST、GraphQL 和事件驅動

在快速發展的軟件開發領域&#xff0c;REST、GraphQL 和事件驅動架構等新的 API 標準對于構建可擴展、高效的系統至關重要。Java 在現代 API 方面以其在企業應用中的穩定性而聞名&#xff0c;不斷適應這些現代范式的需求。隨著不斷發展的生態系統&#xff0c;Java 在現代 API 方…

浮點數精度問題(CSP38思考)

CSP38的第一題&#xff0c;考到了浮點數的除法&#xff08;當然考完發現其實也可以不涉及浮點數&#xff0c;直接轉化為整型&#xff09;&#xff0c;我第一題一直卡到70、80分&#xff0c;故寫下此文。 浮點數的運算有精度損失問題&#xff0c;那么應該如何解決和避免呢&#…

F5 – TCP 連接管理:會話、池級和節點級操作

在 F5 BIG-IP 中,您可以在池成員級別或節點級別管理流向服務器的流量。節點級別狀態會影響與該節點關聯的所有池,而池成員狀態則僅限于單個池。了解每種方法以及何時使用它們對于順利進行維護窗口和流量管理至關重要。 池級狀態:啟用、禁用、強制離線、移除 在 BIG-IP 配置…

StoreView SQL,讓數據分析不受地域限制

作者&#xff1a;章建&#xff08;處知&#xff09; 引言 日志服務 SLS 是云原生觀測和分析平臺&#xff0c;為 Log、Metric、Trace 等數據提供大規模、低成本、實時的平臺化服務。SLS 提供了多地域支持【1】&#xff0c;方便用戶可以根據數據源就近接入 SLS 服務&#xff0c…

爬蟲基礎學習day2

# 爬蟲設計領域 工商&#xff1a;企查查、天眼查短視頻&#xff1a;抖音、快手、西瓜 ---> 飛瓜電商&#xff1a;京東、淘寶、聚美優品、亞馬遜 ---> 分析店鋪經營決策標題、排名航空&#xff1a;抓取所有航空公司價格 ---> 去哪兒自媒體&#xff1a;采集自媒體數據進…

Golang——10、日志處理和正則處理

日志處理和正則處理 1、logx日志處理1.1、logx簡介1.2、日志初始化與配置1.3、常用方法1.4、配合defer捕獲panic 2、正則處理2.1、正則表達式語法大全2.2、基本匹配2.3、常見函數使用2.4、從html提取漢字demo 1、logx日志處理 1.1、logx簡介 logx 是 go-zero 框架中用于日志記…

【LeetCode】3309. 連接二進制表示可形成的最大數值(遞歸|回溯|位運算)

LeetCode 3309. 連接二進制表示可形成的最大數值&#xff08;中等&#xff09; 題目描述解題思路Java代碼 題目描述 題目鏈接&#xff1a;LeetCode 3309. 連接二進制表示可形成的最大數值&#xff08;中等&#xff09; 給你一個長度為 3 的整數數組 nums。 現以某種順序 連接…