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

一文帶你深入了解Java的自動拆裝箱

 更新時間:2023年11月23日 14:01:01   作者:荼錦AI編程  
Java推出了對于基本數(shù)據(jù)類型的對應(yīng)的對象,將基本數(shù)據(jù)類型轉(zhuǎn)換為對象就稱為裝箱,反之則是拆箱,本文主要為大家介紹了Java自動拆裝箱的原理與應(yīng)用,需要的可以參考下

什么是自動拆裝箱

JDK 1.5開始增加了自動拆裝箱機制,Java保留了一些原始的基本數(shù)據(jù)類型,但由于Java是強面向?qū)ο笳Z言,數(shù)據(jù)類型當(dāng)然也應(yīng)該設(shè)置成對象才是,所以Java也推出了對于基本數(shù)據(jù)類型的對應(yīng)的對象,將基本數(shù)據(jù)類型轉(zhuǎn)換為對象就稱為裝箱,反之則是拆箱

八種基本數(shù)據(jù)類型

基本數(shù)據(jù)類型對象類型
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

Java的大部分字節(jié)碼指令都沒有支持類型byte、char和short,甚至沒有任何指令支持boolean類型。

那么Java底層是如何實現(xiàn)這些數(shù)據(jù)類型的?

事實上編譯器會在編譯期或運行期搞事

  • 將byte和short類型的數(shù)據(jù)帶符號擴展(Sign-Extend)為相應(yīng)的int類型數(shù)據(jù)。
  • 將boolean和char類型數(shù)據(jù)零位擴展(Zero-Extend)為相應(yīng)的int類型數(shù)據(jù)。

在處理boolean、byte、short和char類型的數(shù)組時,也會轉(zhuǎn)換為使用對應(yīng)的int類型的字節(jié)碼指令來處理。因此,大多數(shù)對于boolean、byte、short和char類型數(shù)據(jù)的操作,實際上都是使用相應(yīng)的對int類型作為運算類型來進行的

例如,下面代碼每一行代碼上面的注釋為其部分字節(jié)碼指令

public class Test {
    /*
     *   以下均為整型入棧指令
     *   iconst_1 (-1到5的數(shù)據(jù)使用iconst指令,-1使用iconst_m1指令)
     *   bipush 100 (-128到127[一個字節(jié)]的數(shù)據(jù)使用bipush指令)
     *   sipush 1000 (-32768到32767[二個字節(jié)]的數(shù)據(jù)使用sipush指令)
     *   ldc 40000 (-2147483648到2147483647[四個字節(jié)]的數(shù)據(jù)使用ldc指令)
     */
    public static void main(String[] args) {
        // bipush 100【將整型數(shù)據(jù)100壓入棧】
        byte b1 = 100;
        // bipush 101【將整型數(shù)據(jù)101壓入?!?
        short s1 = 101;
        // bipush 49【將整型數(shù)據(jù)49壓入?!?
        char c1 = '1';
        // iconst_1【將整型數(shù)據(jù)1壓入棧】
        boolean bl1 = false;
    }
}

自動拆裝箱原理

byte與Byte

public class Test {
    public static void main(String[] args) {
        Byte num = 1;
        byte num3 = num;
    }
}

編譯后代碼

public class Test {
    public static void main(String[] args) {
        Byte num = Byte.valueOf(1);
        byte num3 = num.byteValue();
    }
}

從編譯后代碼可以看出,這兩者的轉(zhuǎn)換用了Byte類中的方法,看一下這兩個方法

    // 靜態(tài)內(nèi)部類
	private static class ByteCache {
        private ByteCache(){}

        static final Byte cache[] = new Byte[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Byte((byte)(i - 128));
        }
    }
	
	private final byte value;

    public static Byte valueOf(byte b) {
        // 數(shù)組是不存在負(fù)的下標(biāo)的,所以加上偏移量
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }
	
	public Byte(byte value) {
        this.value = value;
    }

	public byte byteValue() {
        return value;
    }

Byte類在使用的時候就會將[-128,127]范圍的Byte對象緩存進類中,這是用了享元模式的思想存取常用的熱點Byte對象,重復(fù)利用該范圍類的Byte對象,也就是說在這個數(shù)值范圍的Byte對象一直是同一個對象

short與Short、long與Long、char與Character的轉(zhuǎn)換原理和這個相同

(char保存的是ASCII碼,所以只緩存[0,127]的對象)

int與Integer

public class Test {
    public static void main(String[] args) {
        Integer num = 1;
        Integer num2 = 200;
        int num3 = num;
    }
}

編譯后代碼

public class Test {
    public static void main(String[] args) {
        Integer num = Integer.valueOf(1);
        Integer num2 = Integer.valueOf(200);
        int num3 = num.intValue();
    }
}

我們可以看出自動拆裝箱事實上是調(diào)用了Integer類中的方法,來看一下這兩個方法,事實上和byte類似,默認(rèn)[-128,127]的Integer對象被緩存了,但是IntegerCache.high是可能被人為配置過的,如果配置的緩存上限值大于127就會緩存[-128,配置的上限值],在此范圍內(nèi)直接返回緩存的對象,否則就new一個新的Integer對象

	public static Integer valueOf(int i) {
        // IntegerCache.low = -128,IntegerCache.high = 127(默認(rèn))
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

boolean與Boolean

同樣是這兩個方法,由于布爾型只有兩個值,所以直接緩存兩個對象

    public static final Boolean TRUE = new Boolean(true);

    public static final Boolean FALSE = new Boolean(false);

    private final boolean value;

    public Boolean(boolean value) {
        this.value = value;
    }

    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

    public boolean booleanValue() {
        return value;
    }

float與Float以及double與Double

由于浮點數(shù)整數(shù)位相同時小數(shù)位可以有多種情況,比如整數(shù)位為1的有1.321332,1.543635,..................,數(shù)量太多所以沒有某一個浮點數(shù)會被反復(fù)使用,所以沒必要緩存,直接返回一個Float新對象

    public static Float valueOf(float f) {
        return new Float(f);
    }

    public static Double valueOf(double d) {
        return new Double(d);
    }

測試

我們測試一下是否返回的是同一個對象

public class Test {
    public static void main(String[] args) {
        Integer b1 = 10;
        Integer b2 = 10;
        Integer b3 = new Integer(10);
        Integer b4 = new Integer(10);
        System.out.println(b1 == b2); // true
        System.out.println(b2 == b3); // false
        System.out.println(b3 == b4); // false
    }
}

引用類型使用等于比較,比較的是對象是否相同(基本數(shù)據(jù)類型使用 = 進行比較比較的是數(shù)值)

那么b1等于b2說明兩個裝箱類型返回的b1和b2兩個Integer對象是同一個對象,10這個數(shù)值在緩存范圍內(nèi)

而使用構(gòu)造方法返回的對象是兩個不同的對象,所以不相同結(jié)果為false

public class Test {
    public static void main(String[] args) {
        Integer b1 = 1000;
        Integer b2 = 1000;
        System.out.println(b1 == b2);// false
    }
}

而1000這個數(shù)值已經(jīng)沒有緩存了,所以返回的是兩個對象

public class Test {
    public static void main(String[] args) {
        Double b1 = 10.0;
        Double b2 = 10.0;
        System.out.println(b1 == b2);// false
    }
}

由于Double是沒有用緩存的,所以兩個對象一定是不同的

到此這篇關(guān)于一文帶你深入了解Java的自動拆裝箱的文章就介紹到這了,更多相關(guān)Java自動拆裝箱內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • REST架構(gòu)及RESTful應(yīng)用程序簡介

    REST架構(gòu)及RESTful應(yīng)用程序簡介

    這篇文章主要為大家介紹了REST架構(gòu)及RESTful的應(yīng)用程序簡介,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • Java回調(diào)函數(shù)實例代碼詳解

    Java回調(diào)函數(shù)實例代碼詳解

    這篇文章主要介紹了Java回調(diào)函數(shù)實例代碼詳解,需要的朋友可以參考下
    2017-10-10
  • redisson使用lock導(dǎo)致死鎖問題解決

    redisson使用lock導(dǎo)致死鎖問題解決

    本文主要介紹了redisson使用lock導(dǎo)致死鎖問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-12-12
  • 最新評論

    威宁| 永寿县| 海兴县| 阳东县| 元谋县| 桐城市| 哈尔滨市| 湖南省| 东宁县| 阜城县| 施秉县| 石屏县| 宣武区| 武强县| 永福县| 星子县| 秭归县| 深州市| 上栗县| 宁晋县| 博湖县| 北流市| 通江县| 苏州市| 万源市| 洞头县| 家居| 邵武市| 新乡市| 平利县| 西华县| 兴仁县| 新竹县| 岳池县| 洛扎县| 荔波县| 肇东市| 和田市| 德昌县| 连江县| 南和县|