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

一文帶你深入了解Java的自動(dòng)拆裝箱

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

什么是自動(dòng)拆裝箱

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

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

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

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

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

事實(shí)上編譯器會(huì)在編譯期或運(yùn)行期搞事

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

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

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

public class Test {
    /*
     *   以下均為整型入棧指令
     *   iconst_1 (-1到5的數(shù)據(jù)使用iconst指令,-1使用iconst_m1指令)
     *   bipush 100 (-128到127[一個(gè)字節(jié)]的數(shù)據(jù)使用bipush指令)
     *   sipush 1000 (-32768到32767[二個(gè)字節(jié)]的數(shù)據(jù)使用sipush指令)
     *   ldc 40000 (-2147483648到2147483647[四個(gè)字節(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;
    }
}

自動(dòng)拆裝箱原理

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類中的方法,看一下這兩個(gè)方法

    // 靜態(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類在使用的時(shí)候就會(huì)將[-128,127]范圍的Byte對(duì)象緩存進(jìn)類中,這是用了享元模式的思想存取常用的熱點(diǎn)Byte對(duì)象,重復(fù)利用該范圍類的Byte對(duì)象,也就是說(shuō)在這個(gè)數(shù)值范圍的Byte對(duì)象一直是同一個(gè)對(duì)象

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

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

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

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

	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

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

    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

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

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

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

測(cè)試

我們測(cè)試一下是否返回的是同一個(gè)對(duì)象

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

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

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

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

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

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

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

由于Double是沒有用緩存的,所以兩個(gè)對(duì)象一定是不同的

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

相關(guān)文章

  • Java Convert Kotlin空指針異常的解決方法

    Java Convert Kotlin空指針異常的解決方法

    本文主要介紹了Java?Convert?Kotlin空指針異常的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 養(yǎng)成良好java代碼編碼規(guī)范

    養(yǎng)成良好java代碼編碼規(guī)范

    這篇文章主要介紹了如何養(yǎng)成良好java代碼編碼規(guī)范,規(guī)范需要平時(shí)編碼過(guò)程中注意,是一個(gè)慢慢養(yǎng)成的好習(xí)慣,下面小編就帶大家來(lái)一起詳細(xì)了解一下吧
    2019-06-06
  • 淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題

    淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題

    本篇文章主要介紹了淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題,具有一定的參考價(jià)值,有需要的可以了解一下
    2017-08-08
  • Spring學(xué)習(xí)之開發(fā)環(huán)境搭建的詳細(xì)步驟

    Spring學(xué)習(xí)之開發(fā)環(huán)境搭建的詳細(xì)步驟

    本篇文章主要介紹了Spring學(xué)習(xí)之開發(fā)環(huán)境搭建的詳細(xì)步驟,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07
  • springcloud整合seata的實(shí)現(xiàn)代碼

    springcloud整合seata的實(shí)現(xiàn)代碼

    這篇文章主要介紹了springcloud整合seata的實(shí)現(xiàn)方法,整合步驟通過(guò)引入spring-cloud-starter-alibaba-seata?jar包,文中結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • Kafka中的producer攔截器與consumer攔截器詳解

    Kafka中的producer攔截器與consumer攔截器詳解

    這篇文章主要介紹了Kafka中的producer攔截器與consumer攔截器詳解,Producer 的Interceptor使得用戶在消息發(fā)送前以及Producer回調(diào)邏輯前有機(jī)會(huì)對(duì)消息做 一些定制化需求,比如修改消息等,需要的朋友可以參考下
    2023-12-12
  • SpringBoot中引入MyBatisPlus的常規(guī)操作

    SpringBoot中引入MyBatisPlus的常規(guī)操作

    這篇文章主要介紹了SpringBoot中引入MyBatisPlus的常規(guī)操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • SpringBoot?分模塊開發(fā)的操作方法

    SpringBoot?分模塊開發(fā)的操作方法

    這篇文章主要介紹了SpringBoot?分模塊開發(fā)的操作方法,通過(guò)在原項(xiàng)目新增一個(gè)maven模塊,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • Java詳解HashMap實(shí)現(xiàn)原理和源碼分析

    Java詳解HashMap實(shí)現(xiàn)原理和源碼分析

    這篇文章主要介紹了Java關(guān)于HashMap的實(shí)現(xiàn)原理并進(jìn)行源碼分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Java8實(shí)現(xiàn)對(duì)List<Integer>的求和

    Java8實(shí)現(xiàn)對(duì)List<Integer>的求和

    這篇文章主要介紹了Java8實(shí)現(xiàn)對(duì)List<Integer>的求和方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評(píng)論