Interger一些關於==和equals的知識
阿新 • • 發佈:2018-12-19
以前一直忽略的知識現在補上
public class MainTest {
public static void main(String args[]) {
Integer integer_one = 3;
Integer integer_two = 3;
Integer integer_three = 129;
Integer integer_four = 129;
Integer intger_five = new Integer(3);
int int_one = 3;
boolean reult1 = integer_one == integer_two;
boolean reult2 = integer_one == int_one;
boolean result3 = integer_three == integer_four;
boolean result4 = int_one == intger_five;
System.out.println(reult1);
System.out.println(reult2);
System.out.println(result3) ;
System.out.println(result4);
}
}
輸出:
true true false true
以前一直不理解 卻忘記了補充 ,永遠要對知識充滿一個敬畏之心 首先要理解 輸出結果必須要懂的從位元組碼層面去看:
將上面的程式碼反編譯後:
如果看不懂位元組碼 的話,總可以看到位元組碼的註釋部分吧?
這裡直接來說明位元組碼層面體現的問題
當Integer
直接賦予一個數字時,將呼叫valueOf方法進行返回。
比如如下程式碼:
Integer integer_one = 3;//它等價於 Integer integer_one = Integer.valueOf(3);
我們來看看valueOf
做了哪些手腳
//Integer.java
public static Integer valueOf(int i) {
//IntegerCache.low==-128
//IntegerCache.high ==127 大家不信的話可以待會可以看看下文分析
//當傳入的資料在一個位元組範圍內(-128到127) 時,返回快取區的引用
if (i >= IntegerCache.low && i <= IntegerCache.high)
//IntegerCache為內部類 cache為一個Integer陣列
return IntegerCache.cache[i + (-IntegerCache.low)];
//如果不在一位元組範圍內重新建立
//所以不管如何 Integer =3 將是一個new物件的引用
return new Integer(i);
}
如果想控制快取請使用虛擬機器引數:-XX:AutoBoxCacheMax=<size>
//Integer.java
//這個類為Integer內部類
private static class IntegerCache {
/***
已刪除無關緊要程式碼
***/
static final int low = -128;
static final int high;
static final Integer cache[];
static {
/***
已刪除無關緊要程式碼
***/
int h = 127;
high = h;
cache = new Integer[(high - low) + 1];
}
private IntegerCache() {}
}
所以得出一個結論: 當預設不改變虛擬機器快取設定。那麼Integer直接賦予一個小於一位元組的直接數值時,將返回事先已經有的Integer物件。
故:
Integer integer_one = 3; nteger integer_two = 3;
比較時將相等,因為兩者都小於一個位元組範圍 ,所以兩者指向同一快取物件
Integer integer_three = 129; Integer integer_four = 129;
比較時將相等,因為兩者都大於一個位元組範圍 ,所以兩者建立時都用了new Integer方法。而==號在java中時比較兩個物件引用是否為同一地址。故兩者比較時返回不相等
大家在看上圖位元組碼圖片的時候,是不是看到intValue方法被呼叫?不記得看不懂沒關係,請繼續看下文。
當一個Integer物件和一個int基本型別比較時,虛擬機器首先會呼叫Integer的 intValue方法返回一個int數值進行比較
對應方法如下:
//Integer.java
public Integer(int value) {
this.value = value;
}
舉例說明:
int int_one = 3;
Integer intger_five = new Integer(3);
Integer integer_one = 3;
//以下程式碼等價於
//boolean result4 = int_one== intger_five.intValue()//返回int型別的數值因為和int_one數值相等所以為true
boolean result4 = int_one == intger_five;
//同上
boolean reult2 = integer_one == int_one;
關於Integer
的equals
方法比較簡單 不在做詳細舉例說明了
請先看equals方法
//Integer.java
//如果傳入的是int型別那麼啟用自動裝箱機制 變為Integer型別
public boolean equals(Object obj) {
//如果是Integer型別那麼直接比較他們的int數值大小即可
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}