案例:
public class TestString {
public static void main(String[] args) {
//棧中開闢一塊空間存放引用t1,在方法區String池中開闢一塊空間,存放String常量"helloworld",
String t1 = "helloworld";
String t2 = "hello";
String t3 = "world";
/**步驟:
1) 棧中開闢一塊中間存放引用t2,t3指向池中String常量"hello",
2) 棧中開闢一塊中間存放引用s2,s2指向池中String常量"world",
3) 棧中開闢一塊中間存放引用t4,
4) t2+ t3通過StringBuilder的最後一步toString()方法還原一個新的String對象"helloworld",因此堆中開闢一塊空間存放此對象,
5) 引用t4指向堆中(t2 + t3)所還原的新String對象,
*/
String t4 = t2 + t3;
/**步驟:
1) 棧中開闢一塊空間存放引用t5,
2) 根據編譯器合併已知量的優化功能,池中開闢一塊空間,存放合併後"helloworld"的String常量中已經存在,直接指向引用,
3) 引用t5指向池中常量"helloworld",
*/
String t5 = "hello" + "world";
/**步驟:
1) 棧中開闢一塊空間存放引用t6,
2) 堆中開闢一塊空間存放一個新建的String對象"helloworld",
3) 引用t6指向堆中的新建的String對象"helloworld",
*/
String t6 = new String("helloworld");
String t7 = new String("helloworld");
System.out.print("t1==t4---> ");
System.out.println(t1 == t4);
System.out.print( "t1.equals(t4)--->");
System.out.println( t1.equals(t4));
System.out.print("t1==t5---> ");
System.out.println( t1 == t5);
System.out.print( "t1.equals(t5)--->");
System.out.println( t1.equals(t5));
System.out.print("t1==t6---> ");
System.out.println( t1 == t6);
System.out.print( "t1.equals(t6)--->");
System.out.println( t1.equals(t6));
System.out.print("t7==t6---> ");
System.out.println( t7 == t6);
System.out.print( "t7.equals(t6)--->");
System.out.println( t7.equals(t6));
}
}
執行結果:
內存圖(有不對的可以指出,謝謝):
總結:
1.因爲t1和t5 定義的都爲helloword。雖然t1有+號,但是內存地址還是都一樣的。
但是t4=t2+t3,t2是一個獨立的內存地址,t3也是;然而t2+t3,所以導致內存地址和t1和t5不一致;
t6,t7爲兩個不同的對象;
2.==比較的是內存地址與hashCode無關;
“`