什麼叫裝箱 & 拆箱?
將int基本型別轉換為Integer包裝型別的過程叫做裝箱,反之叫拆箱。
先看一段程式碼
public static void main(String[] args) { Integer a = 127, b = 127; Integer c = 128, d= 128; System.out.println(a == b); // true System.out.println(c == d); // false }
不知道還有沒有人不知道這段程式碼出現true和false的原因。由此我們引出了Java裝箱的這個操作。我們帶著疑問去進行分析。
裝箱(valueOf())
public static Integer valueOf(int i) { // -128 - 127 if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
我們可以發現,在最開始有一個判斷,如果這個值的範圍在[-128,127]之間,那麼就從這個快取( Integer數組)中取,如果不在這個範圍那麼直接new一個。
為什麼要有[-128,127]的快取?
我說說的理解,因為在我們的業務中,可能存在各種狀態和標識等Integer類型的字段,這些值一般都是0,1,2,3之類的,而且出現的比較頻繁,如果沒有緩存,那麼就需要頻繁的new對象,然後再釋放,就非常消耗內存空間,所以對於這個緩存就出現了,可以極大的幫助我們優化一些空間上的浪費。
為什麼是[-128,127]?
這個我看了一下,具體為什麼這裡就不詳說了,主要還是依賴電腦基礎知識,在你了解了什麼是原碼、反碼、補碼。就很容易知道為什麼是這個範圍區間了。
這個值也是可以透過啟動參數來更改的。
-XX:AutoBoxCacheMax=(size)
自動裝箱帶來的效能問題
那麼看到現在你應該要明白上面程式碼出現不同結果的原因了,那你有沒有想過,例如我們業務中一個for循環中,出現了統計數據類似這樣的操作,如果存在自動裝箱,那麼會出現什麼問題?我們來看下面一段程式碼。
public static void main(String[] args) { long startTime = System.currentTimeMillis(); Integer count = 0; // int count = 0; for (int i = 0; i < 5000000; i++) { count += i; } System.out.println("计算时长:" + (System.currentTimeMillis() - startTime) + " ms"); } // 执行结果: // Integer 计算时长:51 ms // int 计算时长:6 ms
那麼透過執行結果可以明顯的發現自動裝箱頻繁的new物件、分配內存,造成時間和空間上的效能損耗。
小總結
透過上面的原始碼閱讀和測試分析,我們可以得出結論,我們平時在進行計算統計,或者方法入參的時候,應該盡量的避免這種類型轉換的問題。來提升我們整個程式碼的執行效率。
拆箱(intValue)
拆箱整體沒有什麼複雜的邏輯,直接傳回這個數值的基本型別。
補充:自動裝箱、拆箱總是會發生嗎?
其實不一定。看下面的一段範例程式碼,輸出結果已被註解在輸出語句後面。
public static void main(String[] args) { // TODO 自动生成的方法存根 Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; System.out.println(c==d);//true //包装类的==在没有遇到算术运算的情况下不会自动拆箱 System.out.println(e==f);//false System.out.println(c==(a+b));//true System.out.println(c.equals(a+b));//true System.out.println(g==(a+b));//true //equals方法不会处理数据转型关系 System.out.println(g.equals(a+b));//false }
發生自動裝箱、拆箱的情況如下:
自動裝箱:基本型別賦值給包裝型別。如:Integer i1 = 1;
自動拆箱:
#包裝類型賦值給基本型別。如:int i2 = new Integer(1);
int型別與Integer型別比較。 int類型與Integer類型比較如果值相等則結果總是為true。
Integer類型遇到算術運算
#但是為什麼在上例中,System.out.println(c==d);與System.out.println(e==f);輸出的結果不一樣呢?
主要是因為Integer.valueOf()方法。 Integer的部分原始碼貼在下面:
// private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
IntegerCache 是Integer的靜態內部類,valueOf()是包裝方法。從原始碼可以看出,cache是快取數組,當valueOf()方法的入參i在[-128,127]區間內,就會傳回快取數組中的Integer值,否則會重新new一個Integer。
這就是System.out.println(c==d);與System.out.println(e==f);輸出結果不同的原因。 c和d在快取區間內,所以回傳的是同一個引用;而e和f不在快取區間內,回傳的都是new Integer,已經不是同一個引用。
以上是Java 的自動裝箱與拆箱源碼分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JVM的工作原理是將Java代碼轉換為機器碼並管理資源。 1)類加載:加載.class文件到內存。 2)運行時數據區:管理內存區域。 3)執行引擎:解釋或編譯執行字節碼。 4)本地方法接口:通過JNI與操作系統交互。

JVM使Java實現跨平台運行。 1)JVM加載、驗證和執行字節碼。 2)JVM的工作包括類加載、字節碼驗證、解釋執行和內存管理。 3)JVM支持高級功能如動態類加載和反射。

Java應用可通過以下步驟在不同操作系統上運行:1)使用File或Paths類處理文件路徑;2)通過System.getenv()設置和獲取環境變量;3)利用Maven或Gradle管理依賴並測試。 Java的跨平台能力依賴於JVM的抽象層,但仍需手動處理某些操作系統特定的功能。

Java在不同平台上需要進行特定配置和調優。 1)調整JVM參數,如-Xms和-Xmx設置堆大小。 2)選擇合適的垃圾回收策略,如ParallelGC或G1GC。 3)配置Native庫以適應不同平台,這些措施能讓Java應用在各種環境中發揮最佳性能。

Osgi,Apachecommonslang,JNA和JvMoptionsareeForhandlingForhandlingPlatform-specificchallengesinjava.1)osgimanagesdeppedendendencenciesandisolatescomponents.2)apachecommonslangprovidesitorityfunctions.3)

JVMmanagesgarbagecollectionacrossplatformseffectivelybyusingagenerationalapproachandadaptingtoOSandhardwaredifferences.ItemploysvariouscollectorslikeSerial,Parallel,CMS,andG1,eachsuitedfordifferentscenarios.Performancecanbetunedwithflagslike-XX:NewRa

Java代碼可以在不同操作系統上無需修改即可運行,這是因為Java的“一次編寫,到處運行”哲學,由Java虛擬機(JVM)實現。 JVM作為編譯後的Java字節碼與操作系統之間的中介,將字節碼翻譯成特定機器指令,確保程序在任何安裝了JVM的平台上都能獨立運行。

Java程序的編譯和執行通過字節碼和JVM實現平台獨立性。 1)編寫Java源碼並編譯成字節碼。 2)使用JVM在任何平台上執行字節碼,確保代碼的跨平台運行。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

SublimeText3漢化版
中文版,非常好用

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具