1.String s = new String("abc");【该命令会将"abc"视为一个字符串常量。首先,在常量池中查找是否有该常量:如果没有,就创建;有,就直接引用。假设将常量池中"abc"的内存地址记为0x001。然后,在堆中创建一个对象,对常量池中中举蔽"abc"的地址进行引用,并有了自己的内存地址假设记为0x0003。那么此时,s的就是对这个堆中0x0003这个地址的引用。】
2.String s1 = "abc";【该命令会将"abc"视为一个字符串常量。首先,在常卖州量池中查找是否有该常量:如果没有,就创建;有,就直接引用。由第1步知,已有,所以s1就是对常量池中0x001这个地址的引用。】
3.System.out.println(s == s1);//结果:false【==比较的是两个地址引用。很明显,s引用的地址为0x001,s1引用的地址为0x0003,所以为false】
4.System.out.println(s.equals(s1));//结果:true【equals比较的是两个对象的内容。s和s1的内容都是字符串"abc",所以为true】
5.我们再看下面这题:
String s1 = “abc”;
String s2 = “ab” + “c”;
String s3 = “ab”;
String s4 = “c”;
String s5 = s3 + s4;
System.out.println(s1 == s2);//结果:true
【答咐s2只不过是对"abc"进行拼接,和s1都是对常量池中"abc"的引用,所以引用的地址相同,s1==s2。故结果为true】
System.out.println(s1.equals(s2));//结果:true
【比较内容。故结果为true】
System.out.println(s1 == s5);//结果:false
【两个变量相加相当于在堆中new了一个新对象。故结果为false】
System.out.println(s1.equals(s5));//结果:true
【比较内容。故结果为true】
当你理解“引用”时,就基本理解了。