例1
String a="a1";
String b = "a"+1;
System.out.println(a==b);
//返回结果为:turn
//对于基本类型和引用类型 == 的作用效果是不同的,基本类型:比较的是值是否相同;
//引用类型:比较的是引用是否相同;
//a和b在常量池上是同一份字符串常量,a和b同时指向“a1”,两个指向的内存空间相同
例2
String a = "a1";
String bb = "1";
String b = "a" + bb;
System.out.println(a == b);
//返回结果为:false
//字符串变量a指向常量池中的“ab”,而表达式中b=“a”+bb的bb是字符串变量,
//所以字符串变量b不能存储在字符串常量池中,要在堆中新建一个字符串对象存储“ab”,
//两个指向的内存空间不同!!!因此输出false
例3
public static void main(String[] args) {
String a = "a1";
final String bb = getB();
String b = "a" + bb;
System.out.println(a == b);
}
private static String getB() {
return "1";
}
//返回false
//因为getB()相当于newString(“b”);在堆内存中创建了对象,所以b指向的是堆内存中
//的对象,而a指向的是字符串常量池中的字符串,所以两个指向的不是同一个“a1”.
例4
String a = "a1";
final String bb = "1";
String b = "a" + bb;
System.out.println(a == b);
//返回结果为:true
//因为final定义了bb为字符串常量,因此表达式b= “a”+1是确定的,因此a和b同时指向字符串常量池中的“a1”
例5
private static String a = "a1";
public static void main(String[] args){
String s1 = "a";
String s2 = "1";
String s = s1 + s2;
System.out.println(s == a);
System.out.println(s.intern() == a);
}
//返回结果分别为false、true
//第一个返回为false,因为a是指向字符串常量池中“a1”的变量,而s=s1+ s2,s1和s2是变量,是不确定的,不能再存储在字符串常量池中,而是存储在堆中新建的字符串对象,因此a和s指向的不是同一个字符串
//第二个返回为true,原因当String调用intern方法时,如果池中已经包含一个等于此String对象的字符串(用equals(Object)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象的引用。两个变量指向的是同一个“a1”
例6
private static String aa = new String("a1");
public static void main(String[] args){
String s1 = "a";
String s2 = "1";
String s = s1 + s2;
System.out.println(s == aa);
System.out.println(s.intern() == aa);
System.out.println(s.intern() == aa.intern());
}
//第一个输出是false。aa是在堆中分配的对象字符串“a1”,而s是在堆中新建一个对象存储字符串,所以两个变量指向不同的内存空间
//第二个输出是false,s.intern()将字符串添加到常量池中了,而aa还是指向堆空间的引用,因此两个字符串变量指向的是不同的内存空间
//第三个输出true,s.intern()和aa.intern()都是将堆中的字符串添加到字符串常量池中,在常量池中维护的是同一份数据,因此两个指向的是同一个字符串常量“a1”