Java類型系列--基本數據類型

其他網址

JAVA中Long與Integer比較容易犯的錯誤(比較數據equals)_java_我主要負責轉載優秀的技術博文-CSDN博客

另見:《Java開發實戰經典》=> 6.12 包裝類

簡介

問題起源:Long或Integer如何比較大小呢?

  • 錯誤方法:
    直接使用==來比較。 因爲Long與Ineger都是包裝類型,是對象。  而不是普通類型long與int
    使用equals方法。因爲equals方法只能比較同類型的類,例如兩個都要是Integer類型。
  • 正確方法:用,或者先使用longValue()或intValue()方法來得到他們的基本類型的值然後使用==比較也是可以的。

拆箱與裝箱原理

 裝箱就是將基本數據類型轉化爲包裝類型,那麼拆箱就是將包裝類型轉化爲基本數據類型。

package org.example.a;

public class Demo{
    public static void main(String[] args) {
        //自動裝箱,底層其實執行了Integer a=Integer.valueOf(1);
        Integer a = 10;
        //自動拆箱,底層其實執行了int b=a.intValue();
        int b = a;
    }
}

查看反彙編文件

依次執行如下命令

javac -d . org\example\a\Demo.java

javap -c org.example.a.Demo

輸出結果如下:

E:\work\idea_proj\test_java\src>javap -c org.example.a.Demo
Compiled from "Demo.java"
public class org.example.a.Demo {
  public org.example.a.Demo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: astore_1
       6: aload_1
       7: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
      10: istore_2
      11: return
}

Integer a = 10; 
執行上面那句代碼的時候,系統爲我們執行了:Integer a = Integer.valueOf(10);

int b = a; 
執行上面那句代碼的時候,系統爲我們執行了:int b = a.intValue();

緩存問題

分析過程

其他網址

【JAVA】談談拆箱與裝箱_java_陽陽的博客-CSDN博客

測試代碼

package org.example.a;

public class Demo{
    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        Integer c = 200;
        Integer d = 200;
        System.out.println(a == b);
        System.out.println(c == d);
    }
}

執行結果

true
false

 原因:

Integer有個緩存,原理如下。

 valueOf源碼

    //private static class IntegerCache {
    //    static final int low = -128;
    //    static final int high = 127;
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

        當i的值位於[-128,127]的時候,會直接返回Integer緩存數組中相應對象的引用,如果i大於127或小於-128,會重新創建一個Integer實例,並返回。

        那麼第一條式子a和b的值都在緩存範圍內,因此他們指向同一個對象,因此返回true。c和d的值不在範圍內,都是通過new創建出來的,因此不是同一個對象,返回false。

其他包裝類的緩存

        Byte、Short、Integer、Long、Character的valueOf()實現機制類似。

包裝類 說明
Byte 相同值的Byte比較永遠返回true。因爲byte取值範圍就是[-128,127]。
Short、Integer、Long 相同值在[-128,127]則返回true,不在則返回false
Character 要返回true,只需保證i <= 127。因爲char最小值爲0,本來就大於等於-128。
Float、Double 永遠返回false。因爲其永遠返回新創建的對象,因爲一個範圍內的整數是有限的,但是小數卻是無限的,無法保存在緩存中。
Boolean 只有兩個對象,要麼是true的Boolean,要麼是false的Boolean,只要boolean的值相同,Boolean就相等。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章