6.變數聲明與基本類型(Primitive Type)
- 2020 年 3 月 9 日
- 筆記
本文將會介紹 Java 的基本類型和 Kotlin 的區別。我們知道,Java 的基本類型是 boolean, char, short, int, long, float, double。這些基本類型不是對象,只可以進行基本的數學邏輯運算。Java 雖然打著「一切皆對象」的口號,但在基本類型還是留了一手。他們是特別的存在。
至於為什麼要保留基本類型,真相只有一個:性能。大部分基本類型操作是一條指令就可以完成的,而對象方法調用則需要很多條指令才能完成;另外佔用記憶體相比對象,也小很多。可以說 Java 誕生初期,在概念統一和性能的權衡下,把天平偏向了性能。這也很合理:90 年代時候的硬體速度還非常慢。且 Java 最初是為嵌入式設備而設計的,後面才把目標改為互聯網。
現在市面上大部分的銀行卡,裡面裝的是 Java 虛擬機,開發者通過編寫受限的 Java 程式碼來實現一個叫 Applet 的應用單元,並裝載到銀行卡中。銀行卡被插入後,機器會通過針腳或 NFC 和銀行卡進行通訊。這種技術叫 Java Card 技術。 所謂受限的 Java 程式碼,沒有 String,沒有 JDK,甚至大部分連 int 都不支援。只能用 byte 和 short。因為晶片是 16 位的。 我上一份工作,在銀行卡上實現了三種數字貨幣的交易協議。。
我們不妨把 Java 的面向對象稱為不完全面向對象。那麼是否有「真·面向對象」語言?有的。如 Smalltalk,Python,Kotlin 就是。在他們的編程環境里,沒有基本類型,是真正的「一切皆對象」。這樣帶來的好處是概念的統一。「基本類型」這樣的概念不再被需要,不再需要特別的處理它,所有聲明出來的變數都具有同樣的行為,不再需要區分引用類型和值類型。說到引用類型和值類型,大家在初學 Java 的時候應該都花了不少功夫去理解吧?
當然了,Java 也有基本類型對應的對象封裝。如 int 對應 Integer,float 對應 Float,並且 jdk1.5 之後提供了自動裝箱拆箱的編譯器特性。但因為寫起來比基本類型麻煩,且考慮性能問題,導致如果不是限定場景,大家都不會主動用它們。
而 Kotlin 為了提供完全面向對象的特性,摒棄了基本類型。但 Kotlin 沒有直接使用 Java 的 java.lang.Integer,java.lang.Float 裝箱類,而是另起山頭,創造了 kotlin.Int,kotlin.Float 等類,因為別人寫的程式碼都是 shit,因為 Java 的裝箱類是集成在 JDK 的,無法隨著 Kotlin 版本更新而更新。且在 Kotlin 中,數值類還有擁有額外的編譯特性:
前面說到 Java 因為性能問題,保留了基本類型。那麼 Kotlin 選擇了完全面向對象,那理應要承受一定的性能損失。但其實 Kotlin 在編譯成 jvm 位元組碼的時候,大部分的 Int 都會編譯回 int,小部分會被編譯成 Integer。這個小部分,典型的情況就是你聲明一個變數為可空類型時,即聲明為 Int?,這個時候無法使用 jvm 的基本類型結構。
而我們觀察 kotlin.Int 時,可以看到除了數學運算的運算符重載方法,和強轉的方法(toFloat,toLong 等)外,就沒有其他方法了,而這些方法都可以直接對應基本類型運算的操作。kotlin.Int 聲明為這樣一個簡潔的數值封裝類,讓轉換為 jvm 位元組碼的基本類型鋪平道路。
所以使用 kotlin 的數值類型時,絕大部分場景下,不會有額外的性能開銷。
版權所有,轉載請註明出處: https://sickworm.com/?p=1788