private Deque<Integer> data;
private Deque<Integer> helper;
...
if(helper.peek()==data.peek()){
...
}
在一次編程中發現兩個棧的棧頂元素打印是相等的,但是卻進入不了if語句。後來發現是因爲java中自動裝箱自動拆箱在基本類型int和對象類型Integer之間轉換,在helper.peek()==data.peek()
語句中兩邊都是Integer類型,而==對於對象類型比較的是內存地址。值相同的時候內存地址不一定相同。如下源碼所示:
public final class Integer extends Number implements Comparable<Integer> {
...
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
/**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}
...
}
例如下面代碼:
import java.util.ArrayDeque;
import java.util.Deque;
public class MainTest {
public static void main(String[] args) {
Deque<Integer> a=new ArrayDeque<Integer>();
Deque<Integer> b=new ArrayDeque<Integer>();
a.push(new Integer(1));
b.push(new Integer(1));
System.out.println(a.pop()==b.pop());
}
}
執行結果就是false
.
將代碼中System.out.println(a.pop()==b.pop());
修改爲System.out.println(a.pop().intValue()==b.pop().intValue());
結果爲true
,這是因爲完成了手動拆箱。
可以看到intValue()
的源碼:
/**
* Returns the value of this {@code Integer} as an
* {@code int}.
*/
public int intValue() {
return value;
}
可以看出此時是將基本類型int相比較。
將代碼中System.out.println(a.pop()==b.pop());
修改爲System.out.println(a.pop().equals(b.pop()));
結果爲true
,可以看到Integer裏equals()
方法的源碼如下
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Object是所有類的父類,它的源碼如下:
public boolean equals(Object obj) {
return (this == obj);
}
可以看出Integer類重寫了equal()
方法,即拆箱之後進行比較,比較數值而不是內存地址。
綜上,對象的 ==
比較的是對象內存地址,而equal()
方法要看該對象對equal()
方法的重寫,如果沒有重寫,則和==
的結果是一樣的。
Integer 源碼地址:http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Integer.java