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

Java中的自動(dòng)拆裝箱、基本類型的轉(zhuǎn)換、包裝類的緩存詳解

 更新時(shí)間:2024年12月16日 08:41:30   作者:騎個(gè)小蝸牛  
文章詳細(xì)介紹了Java中數(shù)據(jù)類型的拆裝箱、自動(dòng)拆箱和裝箱,以及包裝類的緩存機(jī)制,包括基本數(shù)據(jù)類型的容量大小、轉(zhuǎn)換規(guī)則和自動(dòng)類型轉(zhuǎn)換等

數(shù)據(jù)類型的拆裝箱

1. 拆箱、裝箱

拆箱

把包裝類轉(zhuǎn)換為基本數(shù)據(jù)類型就是拆箱。拆箱通過(guò)包裝類的xxValue方法實(shí)現(xiàn)。

裝箱

把基本類型轉(zhuǎn)換為包裝類的過(guò)程就是裝箱。裝箱通過(guò)包裝類的valueOf方法實(shí)現(xiàn)。

2. 自動(dòng)拆箱

將包裝類自動(dòng)轉(zhuǎn)化成對(duì)應(yīng)的基本數(shù)據(jù)類型(通過(guò)包裝類的xxValue方法)。

    public static void main(String[] args) {
        int int1 = new Integer(100);
        long long1 = new Long(100);
        double double1 = new Double(100.0);
    }

實(shí)際等于

    public static void main(String[] args) {
        int int1 = new Integer(100).intValue();
        long long1 = new Long(100).longValue();
        double double1 = new Double(100.0).doubleValue();
    }

3. 自動(dòng)裝箱

將基本數(shù)據(jù)類型自動(dòng)轉(zhuǎn)化為對(duì)應(yīng)的包裝類(通過(guò)包裝類的valueOf方法)。

    public static void main(String[] args) {
        Integer int2 = 100;
        Long long2 = 100L;
        Double double2 = 100.0;
    }

實(shí)際等于

    public static void main(String[] args) {
        Integer int2 = Integer.valueOf(100);
        Long long2 = Long.valueOf(100L);
        Double double2 = Double.valueOf(100.0);
    }

4. 自動(dòng)拆裝箱使用場(chǎng)景

將基本類型放入集合類(自動(dòng)裝箱)

集合類只支持包裝類型(不支持基本數(shù)據(jù)類型),但是我們add(基本數(shù)據(jù)類型)也不會(huì)報(bào)錯(cuò),是因?yàn)镴ava給我們做了自動(dòng)裝箱。

實(shí)際等于

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(Integer.valueOf(1));
        list.add(Integer.valueOf(2));
    }

包裝類型和基本類型比較大?。ㄗ詣?dòng)拆箱)

包裝類與基本數(shù)據(jù)類型進(jìn)行比較運(yùn)算,其實(shí)是先將包裝類進(jìn)行拆箱成基本數(shù)據(jù)類型,然后比較。

    public static void main(String[] args) {
        boolean b = new Integer(2) > 1;
    }

實(shí)際等于

    public static void main(String[] args) {
        boolean b = new Integer(2).intValue() > 1;
    }

包裝類型的運(yùn)算(自動(dòng)拆箱)

運(yùn)算中包含包裝類型時(shí),會(huì)將包裝類型自動(dòng)拆箱為基本類型再進(jìn)行運(yùn)算

    public static void main(String[] args) {
        int a = new Integer(1) + 1;
    }

實(shí)際等于

    public static void main(String[] args) {
        int a = new Integer(1).intValue() + 1;
    }

三目運(yùn)算(自動(dòng)拆箱)

value = flag ? value1 : value2

三目運(yùn)算中,如果value1和value2中一個(gè)是基本數(shù)據(jù)類型、另一個(gè)是包裝類型。那么無(wú)論value是基本數(shù)據(jù)類型還是包裝類型,只要根據(jù)判斷結(jié)果從value1和value2選擇的那個(gè)值是包裝類型時(shí),都會(huì)先把包裝類型拆箱為基本數(shù)據(jù)類型,再根據(jù)value的類型來(lái)決定是否再對(duì)值進(jìn)行拆封箱處理。

    public static void main(String[] args) {
        Integer a = null;
        int v1 = true ? 0 : a;// 正常
        int v2 = false ? 0 : a;// 報(bào)錯(cuò)
        Integer v3 = true ? 0 : a;// 正常
        Integer v4 = false ? 0 : a;// 報(bào)錯(cuò)
    }

實(shí)際等于

    public static void main(String[] args) {
        Integer a = null;
        int v1 = true ? 0 : a;// 正常
        int v2 = false ? 0 : a.intValue();// 報(bào)錯(cuò)
        Integer v3 = true ? 0 : a;// 正常
        Integer v4 = false ? 0 : Integer.valueOf(a.intValue());// 報(bào)錯(cuò)
    }

方法的返回值(自動(dòng)拆裝箱)

方法的返回值類型與實(shí)際返回值類型不同時(shí),會(huì)自動(dòng)拆裝箱,變成方法返回值相同的類型。

    //自動(dòng)拆箱
    public int getNum1() {
        return new Integer(1);
    }

    //自動(dòng)裝箱
    public Integer getNum2() {
        return 1;
    }

實(shí)際等于

    //自動(dòng)拆箱
    public int getNum1() {
        return new Integer(1).byteValue();
    }

    //自動(dòng)裝箱
    public Integer getNum2() {
        return Integer.valueOf(1);
    }

5. 自動(dòng)拆裝箱的觸發(fā)時(shí)機(jī)

在編譯期,Java文件編譯稱Class(字節(jié)碼)文件的過(guò)程中觸發(fā)自動(dòng)拆裝箱的動(dòng)作。

通過(guò)查看字節(jié)碼文件可以予以證明。兩種查看字節(jié)碼信息的方式:

1.通過(guò)javac和javap查看

先通過(guò)javac將.java代碼編譯成.class字節(jié)碼,然后通過(guò)javap分析字節(jié)碼。

javac:編譯成class(字節(jié)碼)

javac DemoTest.java

javap:分析字節(jié)碼

javap -verbose DemoTest.class

若出現(xiàn)編碼問(wèn)題,可指定編碼

javac -encoding utf-8 DemoTest.java
javap -encoding utf-8 -verbose DemoTest.class

2.IDEA使用ASM Bytecode Outline插件查看字節(jié)碼

類文件上右鍵->選擇: Show Bytecode outline

面板上的三個(gè)選項(xiàng):

  • Bytecode 表示對(duì)應(yīng)的class字節(jié)碼文件
  • ASMified 表示利用ASM框架生成字節(jié)碼對(duì)應(yīng)的代碼
  • Groovified 對(duì)應(yīng)的是class字節(jié)碼指令

6. 自動(dòng)拆裝箱帶來(lái)的問(wèn)題

  • 包裝對(duì)象之間的數(shù)值比較不能簡(jiǎn)單的使用==,除了特殊有緩存的情況(如Integer的-128~127),其他比較都需要使用equals比較。
  • 如果包裝類對(duì)象為NULL,那么自動(dòng)拆箱就可能會(huì)拋出空指針異常
  • 如果一個(gè)for循環(huán)中有大量拆裝箱操作,會(huì)浪費(fèi)很多資源

基本數(shù)據(jù)類型的轉(zhuǎn)換

1. 容量大小排序

基本數(shù)據(jù)類型容量大小排序(不含布爾類型、容量由小到大):

  • byte<short/char<int<long<float<double
  • byte<<int<long<float<double

2. 轉(zhuǎn)換規(guī)則

  1. 8種基本數(shù)據(jù)類型中,除了布爾類型之外,其他的8中數(shù)據(jù)類型之間都可以相互轉(zhuǎn)換
  2. 任何浮點(diǎn)類型不管占用多少個(gè)字符,都比整數(shù)型容量大
  3. char和short可表示的種類數(shù)量相同,但是char可以取更大的整數(shù)
  4. 整數(shù)的默認(rèn)類型為int,小數(shù)的默認(rèn)類型為double
  5. 小容量向大容量轉(zhuǎn)換,稱為自動(dòng)類型轉(zhuǎn)換(又稱隱式類型轉(zhuǎn)換),不會(huì)丟失精度
  6. 大容量轉(zhuǎn)換成小容量,叫做強(qiáng)制類型轉(zhuǎn)換(又稱顯式類型轉(zhuǎn)換),可能會(huì)會(huì)丟失精度,需要加強(qiáng)制類型轉(zhuǎn)換符。
  7. 當(dāng)整數(shù)字面值沒(méi)有超出byte,short,char的取值范圍,可以直接賦值給byte,short,char類型的變量
  8. 多種數(shù)據(jù)類型混合運(yùn)算,先轉(zhuǎn)換成容量大的那種類型再做運(yùn)算(byte,short,char混合運(yùn)算的時(shí)候,各自先轉(zhuǎn)換成int類型再做運(yùn)算)

3. 自動(dòng)類型轉(zhuǎn)換

小容量向大容量轉(zhuǎn)換,稱為自動(dòng)類型轉(zhuǎn)換(又稱隱式類型轉(zhuǎn)換)。

規(guī)則

  • 小容量的類型轉(zhuǎn)化為大容量的類型自動(dòng)使用自動(dòng)類型轉(zhuǎn)換
  • 整數(shù)類型可以自動(dòng)轉(zhuǎn)化為浮點(diǎn)類型,可能會(huì)產(chǎn)生舍入誤差
  • 字符可以自動(dòng)提升為整數(shù)

4. 強(qiáng)制類型轉(zhuǎn)換

大容量轉(zhuǎn)換成小容量,叫做強(qiáng)制類型轉(zhuǎn)換(又稱顯式類型轉(zhuǎn)換)。

強(qiáng)制類型轉(zhuǎn)換需要在要強(qiáng)制類型轉(zhuǎn)換的前面加上括號(hào),然后在括號(hào)里面加上你要轉(zhuǎn)換的類型。

規(guī)則

  • 大容量的類型轉(zhuǎn)化為大容量的類型必須使用強(qiáng)制類型轉(zhuǎn)換
  • 強(qiáng)制類型轉(zhuǎn)換可能導(dǎo)致溢出或損失精度
  • 浮點(diǎn)數(shù)到整數(shù)的轉(zhuǎn)換是通過(guò)舍棄小數(shù)得到,而不是四舍五入
  • 不能把對(duì)象類型轉(zhuǎn)換為不相干的類型

包裝類的緩存

Java包裝類的緩存機(jī)制,是在Java 5中引入的一個(gè)有助于節(jié)省內(nèi)存、提高性能的功能。

包裝類的緩存只在裝箱(通過(guò)包裝類的valueOf方法來(lái)實(shí)現(xiàn))時(shí)有效。

想必大家一定遇到過(guò)這樣的問(wèn)題:兩個(gè)數(shù)值相等的包裝類型對(duì)象通過(guò)==進(jìn)行比較時(shí),得到的結(jié)果有時(shí)是true,有時(shí)又是false。

這可能就是包裝類的緩存在搗亂:當(dāng)包裝類對(duì)象經(jīng)歷過(guò)裝箱操作,得到的對(duì)象可能是緩存好的對(duì)象,也可能是新創(chuàng)建的對(duì)象。

1. 包裝類型的緩存值范圍

基本類型大小(bit)默認(rèn)值取值范圍包裝類包裝類緩存范圍
byte(字節(jié))80[-2^7,2^7-1]
[-128,127]
Byte[-128,127]
char(字符)16空值(\u0000)
(unicode編碼)
[0,2^16-1]
[0,65535]
Character[0,127]
short(短整數(shù))160[-2^15,2^15-1]
[-32768,32767]
Short[-128,127]
int(整數(shù))320[-2^31,2^31-1]
[-2147483648,2147483647]
Integer[-128,127]
long(長(zhǎng)整數(shù))640L[-2^63,2^63-1]
[-9223372036854774808,9223372036854774807]
Long[-128,127]
float(單精度小數(shù))320.0F[-2^31,2^31-1]
[3.402823e+38,1.401298e-45]
Float無(wú)
double(雙精度小數(shù))640.0[-2^63,2^63-1]
[1.797693e+308,4.9000000e-324]
Double無(wú)
boolean(布爾值)8falsetrue,falseBooleantrue,false

boolean類型的底層是轉(zhuǎn)換為1,0存儲(chǔ)的,所以大小只有一個(gè)字節(jié)(8位)

  • valueOf方法的邏輯是先從判斷值是否在緩存值范圍中。如果在,直接返回緩存中的對(duì)象;如果不在,創(chuàng)建新的對(duì)象。
  • 在 jdk 1.8 所有的數(shù)值類緩沖池中,Integer 的緩沖池 IntegerCache 很特殊,這個(gè)緩沖池的下界是 - 128,上界默認(rèn)是 127,但是這個(gè)上界是可調(diào)的。
  • 在啟動(dòng) jvm 的時(shí)候,通過(guò) -XX:AutoBoxCacheMax=來(lái)指定這個(gè)緩沖池的大小,該選項(xiàng)在 JVM 初始化的時(shí)候會(huì)設(shè)定一個(gè)名為 java.lang.IntegerCache.high 系統(tǒng)屬性,然后IntegerCache 初始化的時(shí)候就會(huì)讀取該系統(tǒng)屬性來(lái)決定上界。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot Shiro授權(quán)實(shí)現(xiàn)過(guò)程解析

    SpringBoot Shiro授權(quán)實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了SpringBoot Shiro授權(quán)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 詳解如何在React中逃離閉包陷阱

    詳解如何在React中逃離閉包陷阱

    眾所周知,JavaScript 中的閉包(Closures)一定是這種語(yǔ)言最可怕的特性之一,另外它可能也是最隱蔽的語(yǔ)言特性之一,我們?cè)诰帉?nbsp;React 代碼時(shí)經(jīng)常會(huì)用到它,但是大多數(shù)時(shí)候我們甚至沒(méi)有意識(shí)到這一點(diǎn),本文小編將和大家一起深入探討如何在React中逃離閉包陷阱
    2023-09-09
  • Java單例模式的講解

    Java單例模式的講解

    今天小編就為大家分享一篇關(guān)于Java單例模式的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • hibernate一對(duì)多關(guān)聯(lián)映射學(xué)習(xí)小結(jié)

    hibernate一對(duì)多關(guān)聯(lián)映射學(xué)習(xí)小結(jié)

    這篇文章主要介紹了hibernate一對(duì)多關(guān)聯(lián)映射學(xué)習(xí)小結(jié),需要的朋友可以參考下
    2017-09-09
  • Spring?boot?集成?MQTT詳情

    Spring?boot?集成?MQTT詳情

    這篇文章主要介紹了Spring?boot?集成?MQTT詳情,MQTT是一種基于發(fā)布/訂閱模式的"輕量級(jí)"通訊協(xié)議,可以以極少的代碼和有限的帶寬為連接遠(yuǎn)程設(shè)備提供實(shí)時(shí)可靠的消息服,下文更多相關(guān)介紹,需要的小伙伴可以參考一下
    2022-04-04
  • SpringCloud修改Feign日志記錄級(jí)別過(guò)程淺析

    SpringCloud修改Feign日志記錄級(jí)別過(guò)程淺析

    OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡(luò)通信的細(xì)節(jié),直接面向接口的方式開(kāi)發(fā),讓開(kāi)發(fā)者感知不到網(wǎng)絡(luò)通信細(xì)節(jié)。所有遠(yuǎn)程調(diào)用,都像調(diào)用本地方法一樣完成
    2023-02-02
  • Maven如何解決添加依賴之后沒(méi)有加載jar包報(bào)錯(cuò)問(wèn)題

    Maven如何解決添加依賴之后沒(méi)有加載jar包報(bào)錯(cuò)問(wèn)題

    這篇文章主要介紹了Maven如何解決添加依賴之后沒(méi)有加載jar包報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Springboot下RedisTemplate的兩種序列化方式實(shí)例詳解

    Springboot下RedisTemplate的兩種序列化方式實(shí)例詳解

    這篇文章主要介紹了Springboot下RedisTemplate的兩種序列化方式,通過(guò)定義一個(gè)配置類,自定義RedisTemplate的序列化方式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • mybatis中bind標(biāo)簽和concat的使用說(shuō)明

    mybatis中bind標(biāo)簽和concat的使用說(shuō)明

    這篇文章主要介紹了mybatis中bind標(biāo)簽和concat的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Spring MVC如何設(shè)置請(qǐng)求頭和響應(yīng)頭的Header

    Spring MVC如何設(shè)置請(qǐng)求頭和響應(yīng)頭的Header

    這篇文章主要介紹了Spring MVC如何設(shè)置請(qǐng)求頭和響應(yīng)頭的Header問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03

最新評(píng)論