Integer包裝類和int基本數據類型的比較總結

設有兩個賦值語句:

a = Integer.parseInt("1024");
b = Integer.valueOf("1024").intValue();

  這裏的a和b都是整數類型變量並且他們的值相等。
  intValue()是把Integer對象類型變成int的基礎數據類型; parseInt()是把String變成int的基礎數據類型; Valueof()是把String轉化成Integer對象類型;(現在JDK版本支持自動裝箱拆箱了),在這串代碼中:parseInt得到的是基礎數據類型int,valueof得到的是裝箱數據類型Integer,然後再通過valueInt轉換成int,所以得到這個結果。
現在對於包裝類和基本數據的比較總結如下:

Integer n1 = new Integer(1000);	
Integer n2 = new Integer(1000);		
int value =1000;		
String a = "1000";				
		
Integer n3=2000,n4=2000;
Integer n5=47,n6=47;
		
int n1_int = n1.intValue();
Integer a_integer = Integer.valueOf(a);
		
System.out.println(value==n1); //true
System.out.println(n1_int==n2); //true 把n1轉成了n1_int爲int型,和Integer的n2比較拆箱,比較值
System.out.println(n1 == n2); //false 引用類型比較的是地址
System.out.println(n3==n4); //false
System.out.println(n5==n6); //true
		
System.out.println(n1.equals(n2)); //true equals內部都轉換成了基本數據類型
System.out.println(a_integer.equals(n2)); //true
  1. System.out.println(value====n1)
      輸出是true,因爲value是Int型,n1是Integer型,兩者在進行====比較的時候,Integer會自動拆箱爲int型,而int屬於基本數據類型,基本數據類型的====比較是比較的值,因此都是1000爲true。

  2. System.out.println(n1_int====n2)
      輸出是true,因爲n1_int是把n1轉成了int類型(intValue方法是把Integer類型轉成int類型),所以還是變成了①的情況int和Integer的比較,拆箱後變成值得比較爲true。

  3. System.out.println(n1====n2)
      輸出是false,因爲n1和n2都是Integer是包裝類型,且n1和n2都new了一個對象,則聲明是在棧中,而對象在堆中,這個時候包裝類型進行====比較比較的就是地址,而n1和n2這是兩個在java堆中的不同的對象,所以返回false。

  4. System.out.println(n3====n4)
      輸出是false,因爲這裏n3和n4還是對象(類比String a = “abc”),n3和n4在虛擬機棧的局部變量表中,但是他們的2000是在常量池裏面的兩個不同的常量,所以n3和n4的====比較比較的是地址,因此返回的是false。

  5. System.out.println(n5====n6)
      輸出的是true,雖然n5和n6都是對象,但是因爲他們對應的值是[-128,127]之間,所以當n5創立好後開始創建n6的時候,他會去緩存中找對應的值,然後把這個值給n6,所以這裏是同一個地址,因此返回的是true。

  6. System.out.println(n1.equals(n2))
      輸出的是true。在講爲什麼之前先說一下對於Object的equals的源碼:

public boolean equals(Object obj) {
     return (this == obj);
}

  我們可以看到,對於object類型他的equals其實就是====號比較,====的比較規則是:如果傳入的是引用類型,則比較的是地址,如果傳入的是基本數據類型,則比較的是值。
  而我們的Integer的equals對上面的equals進行了重寫,當然String也對上面的equals進行了重寫,下面給出Integer的重寫的代碼:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

  這裏的value是我們的n1的值。他會做以下幾件事:
  ①首先他會判斷我們括號的n2是不是Integer類型(或者是子類),如果是則進入if,不是就返回false。
  ②接着讓value和((Integer)obj).intValue()進行比較,value是我們n1的值,是int類型(源碼中是private final int value),====右邊是把我們傳參傳進來的obj(n2)轉成Integer類型,然後調用intValue()方法把Integer類型轉成int類型。
  所以我們的equals方法其實實質性的比較是比較兩個int基本數據類型,也就是值的比較,因此這裏n1.equals(n2)中n1和n2值都是1000,返回true。
  如果是String類型,下面我們給出String類型重寫的equals:

public boolean equals(Object anObject) {
      if (this == anObject) {
          return true;
      }
      if (anObject instanceof String) {
          String aString = (String)anObject;
          if (coder() == aString.coder()) {
              return isLatin1() ? StringLatin1.equals(value, aString.value)
                                : StringUTF16.equals(value, aString.value);
          }
     }
     return false;
}

  他主要完成了以下幾件事:
  ①先比較我們的調用者對象和傳入的參數的anObject對象是不是同一個地址(==),如果是則直接返回true。這個相當於就是自己和自己進行equals了,返回當然就是true。
  ②然後判斷我們傳入的anObject對象是不是String類型或者是String類型的子類,如果是則進入if,對調用者的值(也就是字符串)和參數的值(anObject對象的字符串)進行挨個比較,如果都相等則返回true,否則返回false。
  所以這裏對於String,也相當於是值得比較。

  1. System.out.println(a_integer.equals(n2))
      返回的是true,原理和上面的⑥
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章