案例:
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无关;
“`