【JVM】- 類加載與字節碼結構2

編譯期處理(語法糖)

java編譯器把.java源碼編譯成.class字節碼的過程,自動生成和轉換的一些代碼。

默認構造器

public class Candy01 {
}

編譯成class后的代碼

public class Candy1 {public Candy1(){super();}
}

自動拆裝箱(jdk5加入)

public class Candy02 {public static void main(String[] args) {/*** jdk5之前:* Integer x = Integer.valueOf(1);* int y = x.intValue();*/Integer x = 1; // 自動拆箱int y = x; // 自動裝箱}
}

泛型集合取值

public class Candy03 {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(10); // 實際調用:List.add(Object e)Integer x = list.get(0); // 實際調用的是 Object obj = List.get(int idx);}
}

編譯器在獲取真正字節碼時,需要額外做一個類型轉換的操作:

Integer x = (Integer)list.get(0);

可變參數

public class Candy04 {public static void foo(String... args) {String[] array = args;System.out.println(array);}public static void main(String[] args) {foo("hello", "world");}
}

編譯后的代碼:

public class Candy04 {public static void foo(String[] args) {String[] array = args;System.out.println(array);}public static void main(String[] args) {foo(new String[]{"hello", "world"});}
}

如果調用了foo(),則等價于foo(new String[]{}),創建了一個空數組,而不會直接傳null進去

數組 - foreach循環

public class Candy05_01 {public static void main(String[] args) {int[] array = {1, 2, 3, 4, 5};for(int e : array) {System.out.println(e);}}
}

會被編譯為:

int[] array = new int[]{1, 2, 3, 4, 5};
for(int i = 0; i < array.length; i++) {int e = array[i];System.out.println(e);
}

List - foreach循環

public class Candy05_02 {public static void main(String[] args) {List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);for(Integer i : list) {System.out.println(i);}}
}

會被編譯成:

Iterator it = list.iterator();
while(it.hasNext()) {Integer e = (Integer) it.next();System.out.println(e);
}

foreach循環寫法可以配合數組,以及所有實現了Iterator接口的集合類一起使用

switch - 字符串

public class Candy06_01 {public static void choose(String str) {switch(str) {case "hello": {System.out.println("h");break;}case "world": {System.out.println("w");break;}}}
}

會被編譯成:

public class Candy06_01 {public static void choose(String str) {byte x = -1;switch(str.hashCode()) {case 99162322:  // "hello"的hash值if (str.equals("hello")) {x = 0;}break;case 113318802:  // "world"的hash值if (str.equals("world")) {x = 1;}}switch(x) {case 0:System.out.println("h");break;case 1:System.out.println("w");}}
}

編譯后其實是執行了兩次switch

  • 第一次是根據hash和equals將字符串轉換為相應的byte類型
  • 第二次才是利用byte進行比較。

第一遍使用hashCode進行比較,是為了提高效率,較少可能的比較;而equals是為了防止hash沖突。

switch - 枚舉類

enum Sex {MALE, FEMALE
}
public class Candy06_02 {public static void foo(Sex sex) {switch(sex) {case MALE: {System.out.println("男");break;}case FEMALE: {System.out.println("女");break;}}}
}

編譯后代碼:

public class Candy06_02 {public static void foo(Sex sex) {// 獲取枚舉的序號(MALE.ordinal() = 0, FEMALE.ordinal() = 1)int ordinal = sex.ordinal(); switch (ordinal) {case 0:  // MALESystem.out.println("男");break;case 1:  // FEMALESystem.out.println("女");break;}}
}

枚舉類

enum Sex {MALE, FEMALE
}

轉換后代碼:

public final class Sex extends java.lang.Enum<Sex> {// 枚舉常量(public static final)public static final Sex MALE;public static final Sex FEMALE;// 私有構造函數(enum 不能外部實例化)private Sex(String name, int ordinal) {super(name, ordinal);}// 靜態初始化塊(初始化所有枚舉值)static {MALE = new Sex("MALE", 0);FEMALE = new Sex("FEMALE", 1);$VALUES = new Sex[]{MALE, FEMALE};}// 自動生成的方法:values() 返回所有枚舉值public static Sex[] values() {return (Sex[])$VALUES.clone();}// 自動生成的方法:valueOf(String) 根據名字返回枚舉public static Sex valueOf(String name) {return (Sex)Enum.valueOf(Sex.class, name);}// 內部存儲所有枚舉值的數組private static final Sex[] $VALUES;
}

try-with-resources簡化資源關閉

public class Candy07 {public static void main(String[] args) {/*try(資源變量 = 創建資源對象) {}catch() {}*/try(InputStream is = new FileInputStream("d:\\test.txt")) {System.out.println(is);}catch (Exception e) {e.printStackTrace();}}
}

其中:資源對象需要實現AutoCloseable接口,例如:InputStreamOutPutStreamConnectionStatementResultSet等接口都實現了AutoCloseable接口,使用try-with-resources可以不用寫finally語句,編譯器會幫助我們生成資源關閉的代碼。

上邊代碼被編譯為:

public class Candy07 {public static void main(String[] args) {try {InputStream is = new FileInputStream("d:\\test.txt");Throwable t = null;try {System.out.println(is);}catch (Throwable e1){t = e1; // t是我們代碼中出現的異常throw e1;} finally {// 判斷了資源不為空if(is != null) {// 如果我們的代碼有異常if(t != null) {try {is.close();} catch (Throwable e2) {// 如果close出現異常,作為被壓制異常添加t.addSuppressed(e2);}}else {// 如果代碼沒有異常,close出現的異常就是最后catch塊中的eis.close();}}}}catch (IOException e) {e.printStackTrace();}}
}

如果我們的代碼出現了異常,并且關閉資源的時候又出現了異常,如果想讓這兩個異常都顯示,可以使用壓制異常

例如:

public class Candy08 {public static void main(String[] args) {try (MyResource resource = new MyResource()) {int i = 1 / 0; // 除0異常}catch (Exception e) {e.printStackTrace();}}
}
class MyResource implements AutoCloseable {@Overridepublic void close() throws Exception {throw new Exception("close異常"); // 資源關閉異常}
}

輸出:在這里插入圖片描述
兩個異常都會被拋出

方法重寫時的橋接方法

class A {public Number m() {return 1;}
}
class B extends A {@Override// 子類m方法的返回值是Integer,是父類m方法返回值Number的子類public Integer m() {return 2;}
}

編譯后的代碼:

class B extends A {public Integer m() {return 2;}// 此方法才是真正重寫了父類public Number m()方法public synthetic bridge Number m() {// 調用public Integer m()return m();}
}

橋接方法比較特殊,只對java虛擬機可見,與原來的public Integer m(),沒有命名沖突。

無參的匿名內部類

public class Candy08 {public static void main(String[] args) {Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("ok");}};}
}

編譯后代碼:

// 額外生成的類
final class Candy08$1 implements Runnable {Candy08$1() {}@Overridepublic void run() {System.out.println("ok");}
}
public class Candy08 {public static void main(String[] args) {Runnable runnable = new Candy08$1();}
}

引用局部變量的匿名內部類

public class Candy10 {public static void test(final int x) {Runnable runnable = new Runnable() {public void run() {System.out.println(x);}};}
}

編譯后:

// 額外生成的類
final class Candy10$1 implements Runnable {int val$x;Candy10$1(int x) {this.val$x = x;}public void run() {System.out.println(this.val$x);}}
public class Candy10 {public static void test(final int x) {Runnable runnable = new Candy10$1(x);}
}

這也解釋了為什么匿名內部類里邊使用的變量必須使用final修飾:因為在創建Candy10$1對象時,將x的值賦值給了Candy10$1對象的val$x屬性,所以x的值不會在發生變化了。如果發生變化,那么val$x屬性沒有機會再跟著一起變化了。

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

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

相關文章

WSL2 中安裝 cuDNN?? 的完整指南

以下是關于 ??cuDNN?? 的詳細介紹及在 ??WSL2 中安裝 cuDNN?? 的完整指南&#xff0c;結合權威資料整理而成&#xff1a; &#x1f4da; ??一、cuDNN 深度解析?? ??1. 定義與作用?? ??cuDNN??&#xff08;CUDA Deep Neural Network Library&#xff09;是…

Apache Doris FE 問題排查與故障分析全景指南

前言&#xff1a; FE&#xff08;Frontend&#xff09;是 Apache Doris 集群架構中的“大腦”&#xff0c;負責元數據管理、查詢解析和調度等關鍵任務。一旦 FE 出現問題&#xff0c;整個集群的穩定性和可用性將受到嚴重影響。因此&#xff0c;掌握 FE 故障定位與排查方法對于保…

RK AndroidFramework 內置應用可,卸載,恢復出廠設置恢復安裝

device/rockchip/rk356x/rk3568_r/preinstall_del/Android.mkdevice/rockchip/rk356x/rk3568_r/preinstall_del/Android.mk include $(call all-subdir-makefiles) 拿內置LoyversePos應用做例子 device/rockchip/rk356x/rk3568_r/preinstall_del/preinstall.mk PRODUCT_PACK…

一文了解Blob文件格式,前端必備技能之一

文章目錄 前言一、什么是Blob&#xff1f;二、Blob的基本特性三、Blob的構造函數四、常見使用場景1. 文件下載2. 圖片預覽3. 大文件分片上傳 四、Blob與其他API的關系1. File API2. FileReader3. URL.createObjectURL()4. Response 五、性能與內存管理六、實際案例&#xff1a;…

LLMs 系列實操科普(4)

六、deep research 這是 chatgpt 推出的功能&#xff0c;但我這里是免費用戶&#xff0c;一個月才有 5 次使用機會&#xff0c;而且使用的是輕量化模型版本&#xff0c;相對體驗上比較雞肋一些。 那這個深度思考研究是個什么東西呢&#xff1f; 根據 openai 對其的解釋是&…

若依框架前端調用后臺服務報跨域錯誤

背景&#xff1a;使用若依框架的前后端分離項目&#xff0c;前后端開發在同一個辦公室情況下前端調用后端服務提示如下報錯&#xff1a;Access to XMLHttpRequest at http://ip1:8089/online/layer/dataType from origin http://ip2:6090 has been blocked by CORS policy: Res…

PHP商城源碼:構建高效電商平臺的利器

一、PHP商城源碼的核心優勢 1. **開源免費&#xff0c;降低成本** PHP作為開源語言&#xff0c;擁有龐大的開發者社區&#xff0c;成熟的商城源碼&#xff08;如EcShop、OpenCart&#xff09;可免費獲取&#xff0c;大幅降低企業的技術投入成本。 2. **開發效率高** PHP語法…

【學習筆記】C++代碼規范整理

【學習筆記】C代碼規范整理 一、匿名空間namespace 匿名命名空間&#xff08;Anonymous Namespace&#xff09;是一種特殊的命名空間聲明方式&#xff0c;其作用是將聲明的成員限定在當前編譯單元&#xff08;源文件&#xff09;內可見&#xff0c;類似于使用 static 關鍵字修…

數學復習筆記 29 不定積分

前言 復習的時候時常復習一下以前復習的高數&#xff0c;溫故而知新&#xff0c;可以為師矣。現實生活中有非常多讓我難受的事情&#xff0c;賢者模式的時候也會對一些自己的行為嗤之以鼻&#xff0c;復習考研對其他三門科目都沒有學出來正反饋&#xff0c;只能從數學這兒找一…

微軟因安全漏洞禁用黑暗環境下的Windows Hello面部識別功能

面部識別技術在各種場景中的應用日益廣泛&#xff0c;但身份欺詐事件仍時有發生&#xff0c;這表明即使面部識別也并非萬無一失。在某些情況下&#xff0c;這些系統可能被攻擊者利用。 漏洞發現與應對措施 近期&#xff0c;微軟在Windows 10和11系統中禁用了黑暗環境下使用Wi…

產品經理課程(十五)實戰點評(3)

&#xff08;一&#xff09;復習 需求文檔是產品的說明書 需求文檔包含&#xff1a;修訂記錄、背景、主要流程、詳細功能邏輯、數據上報&#xff0c;發布策略 bug也是需求文檔的一部分 &#xff08;二&#xff09;案例講解 案例一&#xff1a; 一個版本里面的4-5個功能點就比…

大模型量化與剪枝

大模型量化&#xff0c;剪枝 量化有助于減少顯存使用并加速推理 GPTQ 等后訓練量化方法(Post Training Quantization)是一種在訓練后對預訓練模型進行量化的方法。 ### model model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct template: llama3### export export_di…

Oracle 數據庫數據操作:精通 INSERT, UPDATE, DELETE

作者&#xff1a;IvanCodes 日期&#xff1a;2025年6月18日 專欄&#xff1a;Oracle教程 在 Oracle 數據庫中&#xff0c;對表內數據進行增加、修改和刪除操作是通過數據操作語言 (DML - Data Manipulation Language) 來完成的。核心的DML語句包括 INSERT (插入新數據), UPDATE…

推薦使用的Unity插件(InputSystem)

本文將提供更簡潔的步驟和常見問題解決。 一、極簡入門步驟&#xff1a; 安裝&#xff1a;Package Manager中安裝Input System&#xff08;確保Unity版本在2019.4&#xff09; 創建Input Actions&#xff1a; 在Project窗口右鍵 -> Create -> Input Actions 雙擊打開…

清理 Docker 容器日志文件方法

操作總結與問題解析 一、操作目的與背景 用戶旨在清理 Docker 容器日志文件以釋放服務器存儲空間,主要通過以下命令組合完成操作: 查看容器日志空間占用清空指定容器的日志文件驗證容器運行狀態與日志清理效果二、關鍵命令與輸出解析 1. 查看 Docker 容器日志空間占用 du…

圖片壓縮工具 | 按指定高度垂直切割圖片

OPEN-IMAGE-TINY&#xff0c;一個基于 Electron VUE3 的圖片壓縮工具&#xff0c;項目開源地址&#xff1a;https://github.com/0604hx/open-image-tiny ?? 需求描述 在上一篇文章一段代碼利用 snapdom 將 CSDN 博文轉化為長圖片&#xff08;PNG/JPG/PDF&#xff09;中&…

山東大學軟件學院創新項目實訓開發日志——第十七周(二)

目錄 1.優化前端日歷頁面顯示&#xff0c;增加鼠標懸停顯示當日會議基本信息的效果。 2.優化會議計劃生成與會議PPT生成功能&#xff0c;使得能夠加載多頁docx文件與PDF文件 3.優化了會議PPT生成功能&#xff0c;使得可以上傳多個文件并根據多個文件生成會議PPT 4.修改了識…

Ubuntu 使用kubeadm部署k8s系統組件反復重啟的問題

系統&#xff1a;Ubuntu 24.04 LTS 問題現象&#xff1a;kubeadm init 后系統組件proxy、apiserver、etcd等頻繁掛掉重啟 問題原因&#xff1a;cgroup配置問題 解決方法&#xff1a; 編輯系統cgroup默認配置文件 sudo nano /etc/default/grub 將GRUB_CMDLINE_LINUX_DEFAU…

Oracle獲取執行計劃之EXPLAIN PLAN 技術詳解

#Oracle #執行計劃 #EXPLAIN PLAN 一、引言 在Oracle數據庫性能優化中&#xff0c;?執行計劃&#xff08;Execution Plan&#xff09;?是理解SQL語句如何被數據庫處理的關鍵工具。EXPLAIN PLAN是Oracle提供的一種靜態分析SQL執行路徑的方法&#xff0c;它通過生成邏輯執行…

【論文閱讀】Qwen2.5-VL Technical Report

Arxiv:https://arxiv.org/abs/2502.13923 Source code:https://github.com/QwenLM/Qwen2.5-VL Author’s Institution&#xff1a;Alibaba 背景 多模態大模型 多模態大模型MultiModal Large Language Models (MM-LLMs) 的發展可以通過一篇綜述了解&#xff1a;MM-LLMs: Re…