1. 程式人生 > >java中==和equals的區別詳解

java中==和equals的區別詳解

字符 blog 的區別 代碼塊 數組 sss oss 兩種 內存劃分

分析前基礎了解:

一)JVM把內存劃分成兩種:一種是棧內存,一種是堆內存。

  ①在函數中定義的一些基本類型的變量和對象的引用變量(變量名)都在函數的棧內存中分配。

  ②當在一段代碼塊定義一個變量時,Java就在棧中為這個變量分配內存空間,當超過變量的作用域後,Java會自動釋放掉為該變量所分配的內存空間,該內存空間可以立即被另作他用。

  ③堆內存用來存放由new創建的對象(包括由基本類型包裝起來的類:Integer、String、Double,實際上每個基本類型都有他的包裝類)和數組。

二)Object類中的equals方法:
public boolean equals(Object obj) {

return (this == obj);
} // 可以看出Object類中equals方法是用==判斷對象引用是否指向同一內存地址。

三)String類很特殊 ,String類對equals方法進行了重寫,如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {

char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
} //可以看出在String類中equals方法不僅可以用==判斷對象的內存地址是否相等,相等則返回true。如果前面的判斷不成立,接著判斷括號內的對象上是否是String類型,接著判斷兩個字符串對象的的長度是否相等,最後判斷內容是否相等,如果相等則返回true。

四)開始具體分析:

4.1 在基本數據類型中的比較

int num1 = 10;
int num2 = 10;
System.out.println(num1 == num2); //true
//num1 和num2都是int型 它們的值都是10,因此使用”==”當然相等.

4.2 在引用數據類型中的比較
⑴String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true

    ![](http://i2.51cto.com/images/blog/201809/01/c00e1eaaca2f6f2fe06c9643d522c1ef.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
   當執行String s1 = “hello”;這條語句時,會在堆中的字符常量池裏找”chance”這個字符串,若沒有找到,則將”hello”這個字符串放入字符串常量池中.而在棧中開辟一塊名為s1的空間存放”chance”,這塊空間的引用.當執行String s2 =   “hello”;這條語句時,會在堆中的字符串常量池裏找”chance”這個字符串,很顯然,可以找到,於是便把字符常量池裏”chance”這個字符串的引用地址賦給s2,因此s1與s2存放的都是堆中字符常量池中的同一個”chance”的引用,接著System.out.println(s1.equals(s2));這裏的equals在String類中被重寫過,用來比較兩個字符串的實際內容是否相等,即每一個字符是否相等,重寫方法末尾會另做說明!!!因為比較的是字符串內容,s1,s2內容都是chance當然是相等的。       

(2) String ss1 = "aaa";
         String ss2 = new String("aaa");
         System.out.println(ss1 == ss2);  //false
         System.out.println(ss1.equals(ss2));  // true

    ![](http://i2.51cto.com/images/blog/201809/01/b5d497d07116d56b43dd1d597d5f65b9.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

 ss2是new出來的,所以重新分配內存地址,當用==判斷時,返回false,但是兩個字符串的內容相同,所以用equals方法時,返回true。

(3)String sss1 = new String("aaa");
String sss2 = new String("aaa");
System.out.println(sss1 == sss2); //false
System.out.println(sss1.equals(sss2)); // true

  ![](http://i2.51cto.com/images/blog/201809/01/0ea48bf88aaf7a04b5c1a199be34fbf4.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

 sss1和sss2都為new出來的對象,各占有一塊內存空間,所以內存地址不同,但是字符串內容相同。

(4) 非String類,例如StringBuffer類 沒有重寫equals方法,所以不比較內容。==和equals都是比較的內存地址

StringBuffer stringBuffer = new StringBuffer("aaa");
StringBuffer stringBuffer2 = new StringBuffer("aaa");
System.out.println(stringBuffer == stringBuffer2); // false
System.out.println(stringBuffer.equals(stringBuffer2)); // false

java中==和equals的區別詳解