<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
將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裝箱的這個操作。我們帶著疑問去進行分析。
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一個。
我說說的理解,因為在我們的業務中,可能存在各種狀態和標識等Integer型別的欄位,這些值一般都是0,1,2,3之類的,而且出現的比較頻繁,如果沒有快取,那麼就需要頻繁的new物件,然後再釋放,就非常消耗記憶體空間,所以對於這個快取就出現了,可以極大的幫助我們優化一些空間上的浪費。
這個我看了一下,具體為什麼這裡就不詳說了,主要還是依賴計算機基礎知識,在你瞭解了什麼是原碼、反碼、二補數。就很容易知道為什麼是這個範圍區間了。
這個值也是可以通過啟動引數進行更改的。
-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物件、分配記憶體,造成時間和空間上的效能損耗。
通過上面的原始碼閱讀和測試分析,我們可以得出結論,我們平時在進行計算統計,或者方法入參的時候,應該儘量的避免這種型別轉換的問題。來提升我們整個程式碼的執行效率。
拆箱總體沒有什麼複雜的邏輯,直接返回這個數值的基本型別。
其實不一定。看下面的一段範例程式碼,輸出結果已被註釋在輸出語句後面。
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;
自動拆箱:
但是為什麼在上例中,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的自動裝箱拆箱的文章就介紹到這了,更多相關Java自動裝箱拆箱內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45