【Java基礎】Java中new一個對象時,JVM到底做了什么?

Java中new一個對象時,JVM到底做了什么?

在Java編程中,new關鍵字是我們創建對象的最常用方式。但你是否想過,當你寫下new MyClass()時,Java虛擬機(JVM)到底在背后做了哪些工作?今天,我們就來深入探討一下new一個對象時,JVM的完整執行流程。


1. 類加載:對象的藍圖

當你第一次使用new創建一個對象時,JVM會首先檢查這個類是否已經被加載。如果沒有,JVM會通過類加載器(ClassLoader)加載該類的字節碼文件(.class文件)。類加載的過程包括:

  • 加載:將類的字節碼加載到內存中。
  • 驗證:確保字節碼是合法的,不會危害JVM的安全。
  • 準備:為類的靜態變量分配內存并設置默認值。
  • 解析:將符號引用轉換為直接引用。
  • 初始化:執行類的靜態初始化塊(static {})和靜態變量的賦值操作。

類加載完成后,JVM就可以基于這個“藍圖”創建對象了。


2. 內存分配:為對象安家

類加載完成后,JVM會為對象在堆內存(Heap)中分配一塊空間。這塊空間的大小是由對象的成員變量決定的。例如,如果一個類有兩個int類型的變量和一個String類型的變量,那么JVM會分配足夠的內存來存儲這些數據。

注意:Java的堆內存是所有線程共享的,因此內存分配需要考慮線程安全問題。JVM會通過指針碰撞(Bump the Pointer)或空閑列表(Free List)等機制來高效地分配內存。


3. 初始化默認值:清零操作

在內存分配完成后,JVM會將對象的成員變量初始化為默認值。這些默認值包括:

  • 數值類型(如intlongdouble等)的默認值為00.0
  • 布爾類型(boolean)的默認值為false
  • 引用類型(如StringObject等)的默認值為null

這一步確保了對象在構造函數執行之前,所有的成員變量都有一個已知的初始狀態。


4. 執行構造代碼塊:對象的“熱身”

如果類中定義了構造代碼塊(即在類中直接使用{}包裹的代碼),JVM會在調用構造函數之前執行這些代碼。構造代碼塊通常用于執行一些通用的初始化邏輯。

例如:

public class MyClass {{System.out.println("構造代碼塊執行");}
}

無論調用哪個構造函數,構造代碼塊都會被執行。


5. 調用構造函數:對象的“出生”

接下來,JVM會調用與new語句匹配的構造函數。構造函數的主要作用是對對象進行進一步的初始化。例如:

public class MyClass {private int value;public MyClass(int value) {this.value = value;System.out.println("構造函數執行");}
}

在構造函數中,你可以為成員變量賦值,或者調用其他方法來完成對象的初始化。


6. 返回引用:對象的“身份證”

當所有初始化操作完成后,new操作會返回對象在堆內存中的引用。這個引用實際上是一個指向堆內存中對象地址的指針。程序通過這個引用來操作對象。

例如:

MyClass obj = new MyClass(10);

這里的obj就是一個引用,它指向堆內存中MyClass對象的地址。


總結:new操作的完整流程

讓我們用一個簡單的例子來總結new一個對象時的完整流程:

public class MyClass {private int value;{System.out.println("構造代碼塊執行");}public MyClass(int value) {this.value = value;System.out.println("構造函數執行");}public static void main(String[] args) {MyClass obj = new MyClass(10);}
}

輸出結果:

構造代碼塊執行
構造函數執行

從輸出中可以看到,JVM首先執行了構造代碼塊,然后調用了構造函數。


思考:new操作的性能開銷

雖然new操作看起來很簡單,但它背后涉及了類加載、內存分配、初始化等多個步驟,這些操作都會帶來一定的性能開銷。因此,在高性能場景下,我們需要盡量避免頻繁創建對象,或者使用對象池(Object Pool)等技術來優化性能。


結語

通過本文的講解,相信你對Java中new一個對象時的完整流程有了更深入的理解。無論是類加載、內存分配,還是構造代碼塊和構造函數的執行,每一步都是JVM精心設計的。掌握這些底層細節,不僅能幫助你寫出更高效的代碼,還能讓你在面試中脫穎而出。

如果你覺得這篇文章對你有幫助,歡迎點贊、轉發,并在評論區分享你的看法!我們下期再見!


關注我,獲取更多技術干貨!

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

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

相關文章

內網穿透:打破網絡限制的利器

目錄 深入理解內網穿透 內網與外網的奧秘 內網穿透的原理剖析 總結與展望 在如今這個數字化時代,網絡已經成為我們生活和工作中不可或缺的一部分。但你是否遇到過這樣的困擾:在家辦公時,想要訪問公司內部的文件服務器,卻因為網…

【汽車ECU電控數據管理篇】HEX文件格式解析篇章

一、HEX格式文件是啥 HEX 文件是 Intel 公司提出的一種按地址排列的數據信息格式,通常用于存儲嵌入式系統的二進制代碼。它以 ASCII 碼的形式記錄數據,每一行以冒號開頭,包含數據長度、地址、記錄類型、數據和校驗碼等信息。HEX 文件常用于程…

深入理解 CSS pointer-events: none:穿透點擊的魔法

一、什么是 pointer-events: none? pointer-events: none 是一個強大的 CSS 屬性,它控制元素是否響應鼠標/觸摸事件(如點擊、懸停、拖拽)。當設置為 none 時,元素會變得“透明”,事件會直接穿透到下方的元…

【AHK】資源管理器自動化辦公實例/自動連點設置

此處為一個自動連續點擊打開檢查的自動化操作案例,沒有quicker的鼠鍵錄制,不常用了,做個備份 #MaxThreadsPerHotkey 2 ; 這個是核心!!!!確保可以同時運行多個熱鍵或標簽global isRunning : tru…

html css js網頁制作成品——HTML+CSS甜品店網頁設計(5頁)附源碼

目錄 一、👨?🎓網站題目 二、??網站描述 三、📚網站介紹 四、🌐網站效果 五、🪓 代碼實現 🧱HTML 六、🥇 如何讓學習不再盲目 七、🎁更多干貨 一、👨?&#x1f…

Springboot使用Milvus的基本操作

Milvus 先得保證數據的正確安裝并且正確運行 <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId> </dependency> <dependency><groupId>io.milvus</groupId><artifactId>milvu…

初階數據結構(C語言實現)——3順序表和鏈表(2)

2.3 數組相關面試題 原地移除數組中所有的元素val&#xff0c;要求時間復雜度為O(N)&#xff0c;空間復雜度為O(1)。OJ鏈接 力扣OJ鏈接-移除元素刪除排序數組中的重復項。力扣OJ鏈接-刪除有序數組中的重復項合并兩個有序數組。力扣OJ鏈接-合并兩個有序數組 2.3.1 移除元素 1…

【力扣】2619. 數組原型對象的最后一個元素——認識原型與原型鏈

【力扣】2619. 數組原型對象的最后一個元素——認識原型與原型鏈 文章目錄 【力扣】2619. 數組原型對象的最后一個元素——認識原型與原型鏈題目解決方案概述全局上下文函數上下文事件處理程序構造函數上下文類上下文顯式 / 隱式綁定綁定方法和永久 this 上下文 方法 1&#xf…

ubuntu終端指令集 shell編程基礎(一)

磁盤指令 連接與查看&#xff1a;磁盤與 Ubuntu 有兩種連接方式&#xff1b;使用ls /dev/sd*查看是否連接成功&#xff0c;通過df系列指令查看磁盤使用信息。若 U 盤已掛載&#xff0c;相關操作可能失敗&#xff0c;需用umount取消掛載。磁盤操作&#xff1a;使用sudo fdisk 磁…

基于Spark的電商供應鏈系統的設計與實現

目錄 1.研究背景與意義 2、國內外研究現狀 3、相關理論與技術 &#xff08;一&#xff09;分布式計算系統Spark &#xff08;二&#xff09;數據倉庫Hive &#xff08;三&#xff09;讀取服務器本地磁盤的日志數據Flume &#xff08;四&#xff09;分布式消息隊列Kafka …

使用TortoiseGit配合BeyondCompare實現在Git倉庫中比對二進制文件

使用TortoiseGit的比對工具可以直接右鍵&#xff0c;點擊選擇比對和上一版本的變化差異&#xff1a; 但是TortoiseGit只能支持比對純文本文件的變化差異&#xff0c;如果嘗試比對二進制文件&#xff0c;會提示這不是一個有效的文本文件&#xff1a; BeyondCompare可以比對二進制…

BladeX框架接口請求跨域

前端使用代理請求接口&#xff0c;接口可以正常訪問。如果換全路徑請求就跨域。 除了后端要配置跨域 還需要修改配置文件對OPTIONS請求的限制

Vue.js響應式基礎

響應式基礎? API 參考 本頁和后面很多頁面中都分別包含了選項式 API 和組合式 API 的示例代碼。現在你選擇的是 組合式 API。你可以使用左側側邊欄頂部的“API 風格偏好”開關在 API 風格之間切換。 聲明響應式狀態? ref()? 在組合式 API 中,推薦使用 ref() 函數來聲明…

選開源CMS建站系統時,插件越多越好嗎?

在選擇開源CMS建站系統時&#xff0c;插件數量并不是唯一的衡量標準&#xff0c;更不能簡單地說“插件越多就越好”&#xff0c;還是需要綜合評估來考慮選擇結果&#xff0c;以下是有關選擇開源CMS系統時對插件數量的考量。 插件數量的優勢插件數量可能帶來的問題功能豐富性&a…

在VSCode中使用MarsCode AI最新版本詳解

如何在VSCode中使用MarsCode AI&#xff1a;最新版本詳解與使用場景 在當今快速發展的軟件開發領域&#xff0c;人工智能&#xff08;AI&#xff09;技術的應用已經變得越來越普遍。ByteDance推出的MarsCode AI是一款強大的AI編程助手&#xff0c;旨在幫助開發者更高效地編寫代…

mac修改docker的daemon.json 鏡像文件

1、找到daemon.json文件的位置 docker info 可以看出位置在&#xff1a; /Users/spuer/.docker 2. 進入daemon.json 所在的目錄&#xff1a; cd /Users/spuer/.docker3. 查看daemon.json的內容&#xff1a; more daemon.json可以看出&#xff0c;沒有配置registry-mirrors&…

5.10 P-Tuning v2:多層級提示編碼的微調革新

P-Tuning v2:多層級提示編碼的微調革新 一、技術架構解析 #mermaid-svg-4Wy6vkXZi67hY9PZ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4Wy6vkXZi67hY9PZ .error-icon{fill:#552222;}#mermaid-svg-4Wy6vkXZi67h…

Eclipse 編譯項目指南

Eclipse 編譯項目指南 引言 Eclipse 是一款功能強大的集成開發環境&#xff08;IDE&#xff09;&#xff0c;廣泛用于Java、C/C、Python等多種編程語言的開發。在Eclipse中編譯項目是進行軟件開發的基礎步驟。本文將詳細介紹如何在Eclipse中編譯項目&#xff0c;包括項目設置…

【大語言模型】【整合版】DeepSeek 模型提示詞學習筆記(散裝的可以看我之前的學習筆記,這里只是歸納與總結了一下思路,內容和之前發的差不多)

以下是個人筆記的正文內容: 原文在FlowUs知識庫上&#xff0c;如下截圖。里面內容和這里一樣&#xff0c;知識排版好看一點 一、什么是 DeepSeek 1. DeepSeek 簡介 DeepSeek 是一家專注于通用人工智能&#xff08;AGI&#xff09;的中國科技公司&#xff0c;主攻大模型研發與…

【緩存】緩存雪崩與緩存穿透:高并發系統的隱形殺手

緩存雪崩與緩存穿透&#xff1a;高并發系統的隱形殺手 在高并發系統中&#xff0c;緩存是提升性能的重要手段。然而&#xff0c;緩存使用不當也會帶來一系列問題&#xff0c;其中最常見的就是緩存雪崩和緩存穿透。這兩個問題如果不加以解決&#xff0c;可能會導致系統崩潰&…