首先,我们来看一段程序
public class StringCompareTest { public static void main(String[] args) { String s1 = "aaa"; String s2 = "aaa"; System.out.println(s1 == s2); System.out.println("-------------------"); String s3 = new String("aaa"); String s4 = new String("aaa"); System.out.println(s3 == s4); System.out.println("-------------------"); String s5 = "aaa"; String s6 = new String("aaa"); System.out.println(s5 == s6); } }
你们认为输出结果是什么呢?
javac 编译的结果是:true , false , false;
我想很多人看到这要糊涂了,创建的字符串都是“aaa",为什么比较结果如此迥异呢?嘿嘿,下面是我的一些见解。
这里要引人字符串池(StringPool)和堆(heap)的概念。
1、对于第一种情况,首先查找StringPool中是否存在“aaa"对象
如果不存在,则在StringPool中创建一个 “aaa"对象, 然后将StringPool中的这个"aaa"对象的地址返回来,赋给引用变量s,这样s会指向 StringPool中的这个"aaa"字符串对象;
如果存在,则不创建任何对象,直接将StringPool中这个“aaa"对象地址返回来,赋给s引用。因为s1、s2指向同一个对象”aaa",所以结果为true.
2、对于第二种情况,首先在StringPool中查找是否有这个对象
如果有,则不在StringPool创建"aaa"对象,直接在堆中(heap)创建"aaa"对象,将"aaa"对象地址返回 赋给s的引用,导致s指向了堆中创建的这个"aaa"对象;
如果没有,则首先在StringPool中创建一个"aaa"对象,然后再在堆中创建一个"aaa"对象,然后将堆中这个”aaa"对象的地址返回赋给s引用,导致s指向了堆中所创建的这个 “aaa”。因为s3、s4指向堆中两个不同的对象,所以结果为false.
3、 对于第三种情况,s5指向字符串池中的对象,s6指向堆中的对象,所以结果为false.