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

Java中的自動拆裝箱、基本類型的轉換、包裝類的緩存詳解

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

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

1. 拆箱、裝箱

拆箱

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

裝箱

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

2. 自動拆箱

將包裝類自動轉化成對應的基本數(shù)據類型(通過包裝類的xxValue方法)。

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

實際等于

    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. 自動裝箱

將基本數(shù)據類型自動轉化為對應的包裝類(通過包裝類的valueOf方法)。

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

實際等于

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

4. 自動拆裝箱使用場景

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

集合類只支持包裝類型(不支持基本數(shù)據類型),但是我們add(基本數(shù)據類型)也不會報錯,是因為Java給我們做了自動裝箱。

實際等于

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

包裝類型和基本類型比較大?。ㄗ詣硬鹣洌?/strong>

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

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

實際等于

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

包裝類型的運算(自動拆箱)

運算中包含包裝類型時,會將包裝類型自動拆箱為基本類型再進行運算

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

實際等于

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

三目運算(自動拆箱)

value = flag ? value1 : value2

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

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

實際等于

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

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

方法的返回值類型與實際返回值類型不同時,會自動拆裝箱,變成方法返回值相同的類型。

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

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

實際等于

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

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

5. 自動拆裝箱的觸發(fā)時機

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

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

1.通過javac和javap查看

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

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

javac DemoTest.java

javap:分析字節(jié)碼

javap -verbose DemoTest.class

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

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

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

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

面板上的三個選項:

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

6. 自動拆裝箱帶來的問題

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

基本數(shù)據類型的轉換

1. 容量大小排序

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

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

2. 轉換規(guī)則

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

3. 自動類型轉換

小容量向大容量轉換,稱為自動類型轉換(又稱隱式類型轉換)。

規(guī)則

  • 小容量的類型轉化為大容量的類型自動使用自動類型轉換
  • 整數(shù)類型可以自動轉化為浮點類型,可能會產生舍入誤差
  • 字符可以自動提升為整數(shù)

4. 強制類型轉換

大容量轉換成小容量,叫做強制類型轉換(又稱顯式類型轉換)。

強制類型轉換需要在要強制類型轉換的前面加上括號,然后在括號里面加上你要轉換的類型。

規(guī)則

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

包裝類的緩存

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

包裝類的緩存只在裝箱(通過包裝類的valueOf方法來實現(xiàn))時有效。

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

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

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

基本類型大小(bit)默認值取值范圍包裝類包裝類緩存范圍
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(長整數(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
double(雙精度小數(shù))640.0[-2^63,2^63-1]
[1.797693e+308,4.9000000e-324]
Double
boolean(布爾值)8falsetrue,falseBooleantrue,false

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

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

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot Shiro授權實現(xiàn)過程解析

    SpringBoot Shiro授權實現(xiàn)過程解析

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

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

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

    Java單例模式的講解

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

    hibernate一對多關聯(lián)映射學習小結

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

    Spring?boot?集成?MQTT詳情

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

    SpringCloud修改Feign日志記錄級別過程淺析

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

    Maven如何解決添加依賴之后沒有加載jar包報錯問題

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

    Springboot下RedisTemplate的兩種序列化方式實例詳解

    這篇文章主要介紹了Springboot下RedisTemplate的兩種序列化方式,通過定義一個配置類,自定義RedisTemplate的序列化方式,結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • mybatis中bind標簽和concat的使用說明

    mybatis中bind標簽和concat的使用說明

    這篇文章主要介紹了mybatis中bind標簽和concat的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Spring MVC如何設置請求頭和響應頭的Header

    Spring MVC如何設置請求頭和響應頭的Header

    這篇文章主要介紹了Spring MVC如何設置請求頭和響應頭的Header問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03

最新評論