最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中Integer128陷阱

 更新時(shí)間:2025年07月13日 09:32:42   作者:lili-felicity  
本文主要介紹了Java中Integer與int的區(qū)別及裝箱拆箱機(jī)制,重點(diǎn)指出-128至127范圍內(nèi)的Integer值會(huì)復(fù)用緩存對(duì)象,導(dǎo)致==比較結(jié)果為true,下面就來(lái)了解一下

今天在學(xué)習(xí)Java的時(shí)候遇到了下面幾個(gè)問(wèn)題。

public static void main(String[] args) {
        Integer num1 = 127;
        Integer num2 = 127;
        Integer num3 = 128;
        Integer num4 = 128;
        int num5 = 127;
        int num6 = 128;
        System.out.println(num1 == num2);
        System.out.println(num3 == num4);
        System.out.println(num1 == num5);
        System.out.println(num6 == num3);
    }

我會(huì)認(rèn)為這個(gè)問(wèn)題的輸出結(jié)果是true、true、true、true。但是在運(yùn)行的時(shí)候發(fā)現(xiàn),結(jié)果并不是想象中的那樣子。正確答案如下。

??一、Integer和int的聯(lián)系

Java 5 引入了自動(dòng)裝箱(Autoboxing)和拆箱(Unboxing)機(jī)制,允許 int 類型和 Integer 類型之間進(jìn)行自動(dòng)轉(zhuǎn)換。

  • 自動(dòng)裝箱:將 int 類型的值自動(dòng)轉(zhuǎn)換為 Integer 對(duì)象。
  • 自動(dòng)拆箱:將 Integer 對(duì)象自動(dòng)轉(zhuǎn)換為 int 類型的值。

1.1 Integer和int的區(qū)別

1. 類型不同

  • int 是基本數(shù)據(jù)類型,直接存儲(chǔ)整數(shù)值。

  • Integer 是引用類型,存儲(chǔ)的是對(duì)象的引用,指向堆內(nèi)存中的 Integer 對(duì)象。

2. 內(nèi)存使用

  • int 變量在棧內(nèi)存中直接存儲(chǔ)整數(shù)值,占用的內(nèi)存空間固定為 4 個(gè)字節(jié)。

  • Integer 對(duì)象存儲(chǔ)在堆內(nèi)存中,除了存儲(chǔ)整數(shù)值外,還需要額外的內(nèi)存來(lái)存儲(chǔ)對(duì)象的元數(shù)據(jù),因此占用的內(nèi)存空間相對(duì)較大。

3. 空值處理

  • int 是基本數(shù)據(jù)類型,不能為 null

  • Integer 是引用類型,可以賦值為 null,這在某些需要表示 “無(wú)值” 的場(chǎng)景中非常有用。

1.2 Integer和int的相互轉(zhuǎn)換

在上一篇文章當(dāng)中說(shuō)到了類和對(duì)象,Integer并不是八大基本數(shù)據(jù)類型中的一個(gè),Integer是一個(gè)類,類似于上一篇文章說(shuō)到的學(xué)生類。

int轉(zhuǎn)換為Intege:裝箱

看下邊一行代碼。下邊這行代碼的執(zhí)行涉及到了裝箱操作。

Integer num1 = 127;

代碼真正在執(zhí)行的時(shí)候會(huì)變?yōu)橄路降臉幼印_@就是裝箱操作,就是把一個(gè)基本類型的int變量,包裝成一個(gè)引用類型的Integer變量。

Integer num1 = Integer.valueOf(127);

Integer轉(zhuǎn)換為int:拆箱

下方的代碼涉及到拆箱操作。

Integer num1 = 127;
int num2 = num1;

代碼在執(zhí)行的時(shí)候會(huì)變?yōu)檫@個(gè)樣子。這就是拆箱操作。

Integer num1 = Ineger.valueOf(127);
int num2 = num1.intValue();

??二、裝箱

想要知道最開(kāi)始的問(wèn)題,就要具體了解,裝箱到底是如何實(shí)現(xiàn)的,為什么對(duì)127裝箱作比較是true,對(duì)128裝箱后作比較是false,現(xiàn)在來(lái)跟進(jìn)裝箱的代碼。

跟進(jìn)到源碼當(dāng)中,我們發(fā)現(xiàn)這個(gè)方法對(duì)于我們傳入的數(shù)值還進(jìn)行了一次判斷,i要和IntegerCache的low和high作比較,如果在low和high之前,那么就返回一個(gè)值,否則的話就返回一個(gè)new出來(lái)的Integer對(duì)象。

IntegerCache.low

能夠看到,low其實(shí)是一個(gè)值,大小為-128

IntegerCache.high

同樣的,high也是一個(gè)值,只不過(guò)好像沒(méi)有初始值,這里我們先看做127。

對(duì)于一開(kāi)始的問(wèn)題,我們傳進(jìn)來(lái)的值是127。

 Integer num1 = 127;
 Integer num2 = 127;

 那么就會(huì)返回這個(gè)值。

 return IntegerCache.cache[i + (-IntegerCache.low)];

 IntegerCache.cache其實(shí)是一個(gè)Integer數(shù)組,用于存儲(chǔ)一些Integer類創(chuàng)建出的對(duì)象。

那么它可以有哪些對(duì)象呢?看如下代碼。

static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    h = Math.max(parseInt(integerCacheHighPropValue), 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            // Load IntegerCache.archivedCache from archive, if possible
            CDS.initializeFromArchive(IntegerCache.class);
            int size = (high - low) + 1;

            // Use the archived cache if it exists and is large enough
            if (archivedCache == null || size > archivedCache.length) {
                Integer[] c = new Integer[size];
                int j = low;
                for(int i = 0; i < c.length; i++) {
                    c[i] = new Integer(j++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

 這是一個(gè)靜態(tài)初始?jí)K,現(xiàn)在不講太多,只是Integer類加載的時(shí)候會(huì)執(zhí)行里邊的代碼,在這里有對(duì)cache的初始化。我們只需要關(guān)注下邊的部分。

            int size = (high - low) + 1;

            // Use the archived cache if it exists and is large enough
            if (archivedCache == null || size > archivedCache.length) {
                Integer[] c = new Integer[size];
                int j = low;
                for(int i = 0; i < c.length; i++) {
                    c[i] = new Integer(j++);
                }
                archivedCache = c;
            }
            cache = archivedCache;

size就是我們?cè)O(shè)置的(127 + 128) + 1,也就是256。cache初始化的過(guò)程如下。

  1. 根據(jù)low和high計(jì)算size
  2. 初始化一個(gè)size大小的Integer數(shù)組
  3. 對(duì)數(shù)組進(jìn)行賦值操作,也就是數(shù)組的0~255索引為存儲(chǔ)的是-128~127之間的數(shù)字(包括0)

現(xiàn)在我們已經(jīng)知道了,cache就是一個(gè)已經(jīng)初始化好的數(shù)組,里邊存儲(chǔ)了-128~127之間的Integer對(duì)象的引用。那么回到上訪的代碼。如果我們傳入的值在low~high之間,那么就會(huì)直接從這個(gè)cache中拿取已經(jīng)創(chuàng)建好的Integer變量。

 return IntegerCache.cache[i + (-IntegerCache.low)];

現(xiàn)在有一點(diǎn)明白了,如果直接拿取的是已經(jīng)創(chuàng)建好的對(duì)象,是不是就意味著每次拿的時(shí)候獲取的都是同一個(gè)對(duì)象呢?就是這樣子。

Integer num3 = 128;
Integer num4 = 128;

 如果傳入的是128。那么就會(huì)通過(guò)new的方式來(lái)創(chuàng)建Integer對(duì)象,每次new出來(lái)的是一個(gè)全新的對(duì)象,所以通過(guò)new方式創(chuàng)建的對(duì)象在怎么比較也是false,因?yàn)橐妙愋蛯?duì)象之間用==操作,比較的是兩個(gè)對(duì)象的地址是否相同,也就是說(shuō)num3和num4比較的是他們?cè)趦?nèi)存空間的地址是否是相同的,并非比較的他們的內(nèi)容是否都是128。

而num1和num2的比較其實(shí)也是比較地址,但是因?yàn)閚um1和num2指向的是同一個(gè)對(duì)象,所以就是true。

??三、拆箱

拆箱操作就很簡(jiǎn)單了,調(diào)用intValue()方法返回包裝的整數(shù)。

public static void main(String[] args) {
        Integer num1 = 127;
        Integer num2 = 127;
        Integer num3 = 128;
        Integer num4 = 128;
        int num5 = 127;
        int num6 = 128;
        System.out.println(num1 == num2);  // Integer.valueOf(127) == Integer.valueOf(127)
        System.out.println(num3 == num4);  // Integer.valueOf(128) == Integer.valueOf(128)
        System.out.println(num1 == num5);  // num1.intValue() == 127
        System.out.println(num6 == num3);  // num2.intValue() == 128
    }

現(xiàn)在是否對(duì)這個(gè)問(wèn)題了解的更多了一點(diǎn)呢。

到此這篇關(guān)于Java中Integer128陷阱的文章就介紹到這了,更多相關(guān)Java Integer128 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • java  List循環(huán)與Map循環(huán)的總結(jié)

    java List循環(huán)與Map循環(huán)的總結(jié)

    這篇文章主要介紹了java List循環(huán)與Map循環(huán)的總結(jié)的相關(guān)資料,并附代碼實(shí)例,幫助大家學(xué)習(xí)理解,需要的朋友可以參考下
    2016-11-11
  • Java判斷線程池線程是否執(zhí)行完畢

    Java判斷線程池線程是否執(zhí)行完畢

    這篇文章主要介紹了Java判斷線程池線程是否執(zhí)行完畢,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Java8?lambda表達(dá)式的10個(gè)實(shí)例講解

    Java8?lambda表達(dá)式的10個(gè)實(shí)例講解

    這篇文章主要介紹了Java8?lambda表達(dá)式的10個(gè)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • mybatis如何封裝List<String>類型屬性

    mybatis如何封裝List<String>類型屬性

    這篇文章主要介紹了mybatis如何封裝List<String>類型屬性問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Spring Boot 中實(shí)現(xiàn)跨域的多種方式小結(jié)

    Spring Boot 中實(shí)現(xiàn)跨域的多種方式小結(jié)

    Spring Boot提供了多種方式來(lái)實(shí)現(xiàn)跨域請(qǐng)求,開(kāi)發(fā)者可以根據(jù)具體需求選擇適合的方法,在配置時(shí),要確保不僅考慮安全性,還要兼顧應(yīng)用的靈活性和性能,本文給大家介紹Spring Boot 中實(shí)現(xiàn)跨域的多種方式,感興趣的朋友一起看看吧
    2024-01-01
  • SpringBoot中讀取配置的七種方法總結(jié)

    SpringBoot中讀取配置的七種方法總結(jié)

    在Spring Boot應(yīng)用中,讀取配置是一項(xiàng)基礎(chǔ)且重要的任務(wù),Spring Boot提供了多種靈活的方式來(lái)讀取配置,以滿足不同場(chǎng)景下的需求,本文將詳細(xì)介紹Spring Boot中讀取配置的幾種常用方法,需要的朋友可以參考下
    2024-08-08
  • 利用idea生成webservice客戶端超詳解步驟(wsdl文件的使用)

    利用idea生成webservice客戶端超詳解步驟(wsdl文件的使用)

    這篇文章主要給大家介紹了關(guān)于利用idea生成webservice客戶端超詳解步驟,第一次接觸webservice,從采坑到采坑,算是了解了一些,明白了一些,文中通過(guò)代碼以及圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • SpringBoot的application.yml不生效問(wèn)題及解決

    SpringBoot的application.yml不生效問(wèn)題及解決

    這篇文章主要介紹了SpringBoot的application.yml不生效問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • MyBatisPlus中批量插入之如何通過(guò)開(kāi)啟rewriteBatchedStatements=true

    MyBatisPlus中批量插入之如何通過(guò)開(kāi)啟rewriteBatchedStatements=true

    這篇文章主要介紹了MyBatisPlus中批量插入之如何通過(guò)開(kāi)啟rewriteBatchedStatements=true問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Java中JSR303的基本使用詳情

    Java中JSR303的基本使用詳情

    這篇文章主要介紹了Java中JSR303的基本使用詳情,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09

最新評(píng)論

江达县| 太保市| 平乡县| 石景山区| 鹤壁市| 天全县| 特克斯县| 利川市| 班玛县| 苏尼特右旗| 上饶市| 库尔勒市| 安塞县| 平乡县| 景德镇市| 侯马市| 清水县| 页游| 游戏| 双江| 侯马市| 磐石市| 浮山县| 康定县| 五华县| 黄冈市| 谷城县| 涡阳县| 故城县| 文成县| 汕尾市| 文登市| 定西市| 武川县| 沂源县| 苍南县| 襄樊市| 深水埗区| 巧家县| 金华市| 台州市|