JAVA里面判斷兩個字符串是否相等
== 比較引用 , equals 比較值
String a = "abc";
String b = "abc";
System.out.println(a == b);
System.out.println(a.equals(b));
String c = new String("abc");
String d = new String("abc");
System.out.println(c == d); // 在堆里面創建兩個對象,所以引用不同
System.out.println(c.equals(d)); // equals() 比較的是對象的值
String e = "ab" + "c";
System.out.println(a == e);
System.out.println(a.equals(e)); // 在編譯的時候在堆里面創建對象
true
true
false
true
true
true
- 無論在常量池里面還是堆中的對象,用equals()方法比較的都是對象的內容
圖解
- new的時候,會在內存創建一個對象
例子
public class Example{
String str = new String("good");
char[ ] ch = { 'a' , 'b' , 'c' };
public static void main(String args[]){
Example ex = new Example();
ex.change(ex.str,ex.ch);
System.out.print(ex.str + " and ");
System.out.print(ex.ch);
}
public void change(String str,char ch[ ]){
str = "test ok";
ch[0] = 'g';
}
}
結果: good and gbc
-
String確實是個不可變對象,這個不可變是JDK特有的
-
String str = new String("good");是在編譯時在堆棧中創建對象和分配內容,而在傳參的時候,傳遞的是地址,把外面的str引用地址復制了一份給方法內的str而不是里面的內容
-
題目中的形參str只是原引用ex.str的一個引用副本,傳的是一個副本地址值,這個值與ex.str地址值是不一樣的,但是它們同時指向了堆中的對象new String("good"),當你在函數中改變形參也就是地址的副本值也就是這句str="test ok"只是將副本地址指向常量"test ok",並沒有改變原ex.str的指向方向,它還是指向對象new String("good")的
-
char數組與String一樣傳的也是地址的副本,但是關鍵是形參ch它沒有新的指向 ch[0]只是ch在指向原對象時改變了對象的內部結構, 所以在ex.ch指向與它是同一個對象的情況下當然也會隨之變化
-
圖解:
總結
直接賦值而不是使用new關鍵字給字符串初始化,在編譯時就將String對象放進字符串常量池中;使用new關鍵字初始化字符串時,是在堆棧區存放變量名和內容;字符串的拼接操作在程序運行時,才在堆中創建對象。一般,可以認為使用"=="比較的是引用,equals比較的是內容。
凡事有交代,事事有回音