1. 程式人生 > >Java為什麼兩個值相等的物件==比較返回false而兩個值相等的不同型別的的基本資料型別返回true

Java為什麼兩個值相等的物件==比較返回false而兩個值相等的不同型別的的基本資料型別返回true

為什麼Java中==比較兩個值相等的物件返回false,而用==比較兩個值相等,基本資料型別不相同的資料返回true?

先看是不是,再問為什麼。

首先看值相同的兩個物件的==比較:

public class Obj{
    private int num;
    public Obj(int num){
        this.num = num;
    }
}

public class Test{
    public static void main(String[] args){
        Obj obj1 = new Obj(1);
        Obj obj2 = new Obj(1);        
        System.out.println(obj1 == obj2);
    }
}
這個輸出結果應該會一點java的人都知道返回的是false,因為==比較的是是否完全是同一個物件,也就是是否在同一片記憶體空間上。

下面看一下值相等的兩個基本資料型別的==比較:

public class Test{
    public static void main(String[] args){
        int i1 = 1;
        byte i2 = 1;
        System.out.println(i1 == i2);
    }
}
這個輸出結果想必大多數人也能答出來,結果是true。

好,現在來看看為什麼。不要把這些東西想得太想當然,應該儘可能多問一個為什麼。

首先要知道這些區域性變數和引用存放在什麼地方,實際上是存放在區域性變量表裡,這是一組變數值儲存空間,用於存放方法引數和方法內部定義的區域性變數。區域性變數的容量以變數槽(slot)為最小單位,JVM規範沒有明確指出一個slot應該佔有多少記憶體空間,只是說一個slot應該能存放一個boolean、byte、char、short、int、float、reference或者returnAddress型別的資料

說到這裡應該明白了,比如上面的i1,i2都是以值的形式存在於虛擬機器棧中的區域性變量表裡的slot,而且是不同的slot,然而obj1和obj2存的分別是指向不同堆內物件的reference。

那麼值相等的基本資料型別之間用==比較為true以及值相等的物件之間的==比較為false的原因也水落石出了。

==可以看成是比較區域性變量表中的slot中存著的東西,對於值相等的物件的比較,比較的也就是reference,reference指向的Java堆中物件都不同,當然也就不一樣。

當使用==比較值相等的基本資料型別的時候,比較的還是slot中存著的東西,這個時候slot中存著的是基本資料型別的值,所以比較的是基本資料型別的值,所以是相等的。

這是我的個人看法,知乎上有種很多人擁護的看法是對於一個基本資料型別會把它封裝成物件放在堆內,如果有新的資料型別值和他一樣就直接使用這個堆內物件,所以值相等的時候==返回為true,在我看來這樣的解答是很不合理的。

以上均是個人看法,如果有錯誤請指出