欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中Integer128的坑

 更新時間:2025年03月21日 10:15:52   作者:lili-felicity  
本文主要介紹了Java中Integer128的坑,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

今天在學習Java的時候遇到了下面幾個問題。

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);
    }

我會認為這個問題的輸出結果是true、true、true、true。但是在運行的時候發(fā)現(xiàn),結果并不是想象中的那樣子。正確答案如下。

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

Java 5 引入了自動裝箱(Autoboxing)和拆箱(Unboxing)機制,允許 int 類型和 Integer 類型之間進行自動轉換。

  • 自動裝箱:將 int 類型的值自動轉換為 Integer 對象。
  • 自動拆箱:將 Integer 對象自動轉換為 int 類型的值。

1.1 Integer和int的區(qū)別

1. 類型不同

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

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

2. 內(nèi)存使用

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

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

3. 空值處理

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

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

1.2 Integer和int的相互轉換 

在上一篇文章當中說到了類和對象,Integer并不是八大基本數(shù)據(jù)類型中的一個,Integer是一個類,類似于上一篇文章說到的學生類。

int轉換為Intege:裝箱

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

Integer num1 = 127;

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

Integer num1 = Integer.valueOf(127);

Integer轉換為int:拆箱

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

Integer num1 = 127;
int num2 = num1;

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

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

??二、裝箱

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

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

IntegerCache.low

能夠看到,low其實是一個值,大小為-128

IntegerCache.high

同樣的,high也是一個值,只不過好像沒有初始值,這里我們先看做127。

對于一開始的問題,我們傳進來的值是127。

 Integer num1 = 127;
 Integer num2 = 127;

 那么就會返回這個值。

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

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

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

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;
        }

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

            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就是我們設置的(127 + 128) + 1,也就是256。cache初始化的過程如下。

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

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

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

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

Integer num3 = 128;
Integer num4 = 128;

 如果傳入的是128。那么就會通過new的方式來創(chuàng)建Integer對象,每次new出來的是一個全新的對象,所以通過new方式創(chuàng)建的對象在怎么比較也是false,因為引用類型對象之間用==操作,比較的是兩個對象的地址是否相同,也就是說num3和num4比較的是他們在內(nèi)存空間的地址是否是相同的,并非比較的他們的內(nèi)容是否都是128。

而num1和num2的比較其實也是比較地址,但是因為num1和num2指向的是同一個對象,所以就是true。

??三、拆箱

拆箱操作就很簡單了,調(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)在是否對這個問題了解的更多了一點呢。

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

相關文章

  • Java 異常的知識整理

    Java 異常的知識整理

    這篇文章主要介紹了Java 異常的知識整理的相關資料,需要的朋友可以參考下
    2017-07-07
  • Java中有界隊列的飽和策略(reject policy)原理解析

    Java中有界隊列的飽和策略(reject policy)原理解析

    這篇文章主要介紹了Java中有界隊列的飽和策略(reject policy)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • 詳解JavaWeb過濾器 Filter問題解決

    詳解JavaWeb過濾器 Filter問題解決

    過濾器就是對事物進行過濾的,在Web中的過濾器,當然就是對請求進行過濾,我們使用過濾器,就可以對請求進行攔截,然后做相應的處理,實現(xiàn)許多特殊功能,今天主要給大家講解JavaWeb過濾器 Filter問題解決,感興趣的朋友一起看看吧
    2022-10-10
  • 使用jps命令查看Java進程的詳細指南

    使用jps命令查看Java進程的詳細指南

    jps是Java開發(fā)者和系統(tǒng)管理員的得力助手,它簡化了Java進程監(jiān)控的過程,使得快速檢查應用運行狀態(tài)變得輕而易舉,在Java開發(fā)和運維場景中,jps是一個非常實用的命令行工具,本文介紹了如何有效地使用 jps命令來查看Java進程的詳細指南,需要的朋友可以參考下
    2024-10-10
  • 通過端口1433連接到主機127.0.0.1的 TCP/IP 連接失敗,錯誤:“connect timed out”的解決方法

    通過端口1433連接到主機127.0.0.1的 TCP/IP 連接失敗,錯誤:“connect timed out”的解

    這篇文章主要介紹了通過端口1433連接到主機127.0.0.1的 TCP/IP 連接失敗,錯誤:“connect timed out”的解決方法,需要的朋友可以參考下
    2015-08-08
  • SpringBoot 自定義注解異步記錄復雜日志詳解

    SpringBoot 自定義注解異步記錄復雜日志詳解

    這篇文章主要為大家介紹了SpringBoot 自定義注解異步記錄復雜日志詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • 淺談SpringBoot之開啟數(shù)據(jù)庫遷移的FlyWay使用

    淺談SpringBoot之開啟數(shù)據(jù)庫遷移的FlyWay使用

    這篇文章主要介紹了淺談SpringBoot之開啟數(shù)據(jù)庫遷移的FlyWay使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Java中數(shù)組的定義和使用教程(三)

    Java中數(shù)組的定義和使用教程(三)

    這篇文章主要給大家介紹了關于Java中數(shù)組的定義和使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • 舉例詳解Java編程中HashMap的初始化以及遍歷的方法

    舉例詳解Java編程中HashMap的初始化以及遍歷的方法

    這篇文章主要介紹了Java編程中HashMap的初始化以及遍歷的方法,是Java入門學習中的基礎知識,需要的朋友可以參考下
    2015-11-11
  • Java效率提升神器之Guava-Joiner

    Java效率提升神器之Guava-Joiner

    這篇文章主要介紹了Java效率提升神器之Guava-Joiner,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07

最新評論