1. 程式人生 > >Interger一些關於==和equals的知識

Interger一些關於==和equals的知識

以前一直忽略的知識現在補上


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基本型別比較時,虛擬機器首先會呼叫IntegerintValue方法返回一個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;

關於Integerequals方法比較簡單 不在做詳細舉例說明了 請先看equals方法

//Integer.java
//如果傳入的是int型別那麼啟用自動裝箱機制 變為Integer型別
public boolean equals(Object obj) {
		//如果是Integer型別那麼直接比較他們的int數值大小即可
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }