Java整数缓存-为什么Integer.valueOf(127)== Integer.valueOf(127)为True
在一次采訪中,我的一個朋友被問到如果我們有兩個Integer對象, Integer a = 127; Integer b = 127; Integer a = 127; Integer b = 127; 為什么當a == b都持有兩個單獨的對象時,其值為true ? 在本文中,我將嘗試回答這個問題,并嘗試解釋答案。
簡短答案
這個問題的簡短答案是,將int常量直接分配給Integer引用是自動裝箱概念的一個示例,在該示例中,由編譯器處理到對象轉換代碼的常量值,因此在編譯階段,編譯器將Integer a = 127;轉換為Integer a = 127; Integer a = Integer.valueOf(127); 。
Integer類為內部整數維護一個內部IntegerCache,這些整數默認范圍為-128 to 127并且Integer.valueOf()方法從該緩存中返回上述范圍的對象。 因此a == b返回true,因為a和b都指向同一個對象。
長答案
為了理解簡短的答案,讓我們首先了解Java類型,Java中的所有類型都分為兩類
例如int a = 5; int b = 5; int a = 5; int b = 5; 這里a和b直接持有的5二進制值,如果我們試圖比較a和b使用a == b我們實際上是在比較5 == 5返回true。
例如, Integer a = new Integer(5); Integer b = new Integer(5) Integer a = new Integer(5); Integer b = new Integer(5) ,此處a和b不保存二進制值5而是a和b保存兩個單獨對象的內存地址,其中兩個對象都包含值5 。 因此,如果嘗試使用a == b,比較a和b a == b,則實際上是在比較這兩個單獨的內存地址,因此我們得到false ,要對a和b執行實際相等,需要執行a.euqals(b) 。 引用類型又分為4類: 強引用,軟引用,弱引用和幻像引用 。
而且我們知道Java為所有原始類型提供包裝器類,并支持自動裝箱和自動拆箱。
// Example of auto-boxing, here c is a reference type Integer c = 128; // Compiler converts this line to Integer c = Integer.valueOf(128); // Example of auto-unboxing, here e is a primitive type int e = c; // Compiler converts this line to int e = c.intValue();現在,如果我們創建兩個整數對象a和b,并嘗試使用相等運算符==進行比較,則將得到false因為兩個引用都持有不同的對象
Integer a = 128; // Compiler converts this line to Integer a = Integer.valueOf(128); Integer b = 128; // Compiler converts this line to Integer b = Integer.valueOf(128);System.out.println(a == b); // Output -- false但是,如果我們為a和b都分配值127并嘗試使用等于運算符==進行比較,那么為什么會true ?
Integer a = 127; // Compiler converts this line to Integer a = Integer.valueOf(127); Integer b = 127; // Compiler converts this line to Integer b = Integer.valueOf(127);System.out.println(a == b); // Output -- true正如我們在代碼中看到的那樣,我們為a和b分配了不同的對象,但是只有當a和b都指向同一個對象時, a == b才能返回true。
那么比較如何返回true? 這里到底發生了什么? 是a和b指向相同的對象?
到目前為止,我們知道代碼Integer a = 127; 是自動裝箱的示例,編譯器自動將此行轉換為Integer a = Integer.valueOf(127); 。
因此,正是Integer.valueOf()方法返回這些整數對象,這意味著該方法必須在幕后進行某些操作。
并且,如果我們看一下Integer.valueOf()方法的源代碼,我們可以清楚地看到,如果傳遞的int文字i大于IntegerCache.low且小于IntegerCache.high則該方法從IntegerCache返回Integer對象。 IntegerCache.low和IntegerCache.high默認值分別是-128和127 。
換句話說而不是創建和retruning新的整數對象, Integer.valueOf()方法返回整數從內部對象IntegerCache如果傳遞的INT字面大于
-128且小于127 。
Java緩存落入-128到127范圍內的整數對象,因為該整數范圍在日常編程中被大量使用,從而間接節省了一些內存。
如您在下圖中所看到的, Integer類維護一個內部靜態IntegerCache類,該類充當緩存并保存從-128到127的整數對象,這就是為什么當我們嘗試獲取127整數對象時總是得到相同的對象。
當類由于static block而被加載到內存時,首次使用時將初始化緩存。 高速緩存的最大范圍可以由-XX:AutoBoxCacheMax JVM選項控制。
此緩存行為僅適用于Integer對象,類似于Integer.IntegerCache我們還有ByteCache , ShortCache , LongCache , Byte CharacterCache , Short ,
Long , Character 。
Byte,Short和Long具有固定的緩存范圍,介于–127到127(含)之間,而Character的范圍是0到127(含)之間。 只能通過參數對Integer修改范圍,而不能對其他參數進行修改。
您可以在此Github存儲庫中找到本文的完整源代碼,請隨時提供寶貴的反饋。
翻譯自: https://www.javacodegeeks.com/2018/11/integer-cache-integer-valueof127-true.html
總結
以上是生活随笔為你收集整理的Java整数缓存-为什么Integer.valueOf(127)== Integer.valueOf(127)为True的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存泄漏代码_调查内存泄漏第1部分–编写
- 下一篇: 以Spring方式构建企业Java应用程