Java中string类型在内存机制的存储问题

package chapter3;

public class RefAndAdd {
public static void main(String[] args) {
String str = "abc";
String str1 = "ab";
String str2 = str1 + "c";
String str3 = "a" + "b" + "c";
System.out.println(str == str2);
System.out.println(str == str3);
System.out.println(str2 == str3);
}
}

为什么输出结果是false,true,false

有几个点:
1、字符串常量("abc")会存在常量池中;
2、编译的时候会优化代码,其中就有将"a" + "b" + "c"优化成“abc”,然后放在常量池中
3、str1+"c"是在运行期决定的,所有相当于一个新的“abc”,而这个“abc”是堆内存中
4、引用对象进行比较时使用equals,不能使用==,==只是单纯的比较值(对于引用对象而言,就会比较它的引用值---相当于一个地址)

String类型的变量比较时不能用 ==号 需要调用equals函数来完成 比如 “ABC”.equals(a)

str1 + "c"相当于调用了一个new产生了新的实例,我们知道一旦调用了new 不论String内容是否相同,在堆空间中都会开辟新的空间。
"a" + "b" + "c" 这种形式没有调用new,此时字符串常量("abc")存在常量池中,当String内容相同时,在堆空间中不会开辟新的空间。

str1 + "c"相当于调用了一个new产生了新的实例,我们知道一旦调用了new 不论String内容是否相同,在堆空间中都会开辟新的空间。
"a" + "b" + "c" 这种形式没有调用new,此时字符串常量("abc")存在常量池中,当String内容相同时,在堆空间中不会开辟新的空间。

str与str3指向同一引用“abc”,所以相等,但是str2与str、str3指向不同引用,其指向“ab”,所以不等。
用==比较是比较双方的对象,而用equals函数则是比较双方的引用。
可以参考:http://blog.csdn.net/zw_2011/article/details/6431448