㈠ 不了解這12個語法糖,別說你會java!
閱讀本文大概需要 10 分鍾。
Java 編譯原理角度,深入位元組碼及 class 文件,抽絲剝繭,了解 Java 中的語法糖原理及用法,幫助大家在學會如何使用 Java 語法糖的同時,了解這些語法糖背後的原理。
語法糖,也稱糖衣語法,由英國計算機學家 Peter.J.Landin 發明的一個術語,指在計算機語言中添加的某種語法,這種語法對語言的功能並沒有影響,但讓程序員使用更加方便。簡而言之,語法糖讓程序更加簡潔,有更高的可讀性。
Java 中最常用的語法糖主要有泛型、變長參數、條件編譯、自動拆裝箱、內部類等。本文主要來分析下這些語法糖背後的原理。
switch 支持 String 與枚舉:從Java 7 開始,Java語言中的語法糖在逐漸豐富,其中一個比較重要的就是Java 7中switch開始支持String。在編譯階段,通過equals()和hashCode()方法實現字元串的switch。
泛型:Java 使用的是Code sharing的處理機制,將多種泛型類形實例映射到唯一的位元組碼表示上。類型擦除的主要過程是將泛型類的類型參數在編譯時擦除,生成普通類和方法。
自動裝箱與拆箱:自動裝箱和拆箱是自動進行的非人為轉換,原始類型值通過調用包裝器的valueOf方法進行裝箱,通過調用包裝器的xxxValue方法進行拆箱。
可變參數:在Java 1.5中引入的特性,允許一個方法把任意數量的值作為參數。可變參數在被使用的時候,首先會創建一個數組,然後再把這個數組作為參數傳遞到被調用的方法中。
枚舉:Java SE5提供了一種新的類型-Java的枚舉類型,關鍵字enum可以將一組具名的值的有限集合創建為一種新的類型。枚舉是由final類型的類繼承Enum類實現的。
內部類:內部類之所以也是語法糖,是因為它僅僅是一個編譯時的概念。編譯後,內部類與外部類分別生成兩個class文件。
條件編譯:Java語法的條件編譯,是通過判斷條件為常量的if語句實現的。根據if判斷條件的真假,編譯器直接把分支為false的代碼塊消除。
斷言:在Java中,assert關鍵字是從JAVA SE 1.4 引入的,用於避免與老版本的Java代碼中使用了assert關鍵字導致的錯誤。斷言的底層實現就是if語句。
數值字面量:在java 7中,數值字面量允許在數字之間插入任意多個下劃線,這些下劃線不會對字面量的數值產生影響,目的是方便閱讀。
for-each:增強for循環背後其實使用了普通的for循環和迭代器。
try-with-resource:從Java 7開始,jdk提供了一種更好的方式關閉資源,使用try-with-resources語句,編譯器會幫我們處理關閉資源的操作。
lambda表達式:雖然有人可能認為lambda表達式不是語法糖,其實它也是語法糖的一種,實現方式依賴了JVM底層提供的lambda相關api。
可能遇到的坑:例如當泛型遇到重載、當泛型遇到catch或泛型內包含靜態變數時,需要注意避免出現編譯錯誤或潛在的問題。
總結:Java中常用的語法糖讓日常開發更加高效,但使用之前了解其原理避免掉坑同樣重要。