代码
String a = "a";
String b = "b";
String c = "c";
String s1 = "a"+"b"+"c";
String s2 = a+b+c;
System.out.println(s2==s1);
System.out.println(System.identityHashCode(s1));
System.out.println(System.identityHashCode(s2));
粗略解释
首先了解字符串常量池,创建字符串对象分别有两种,一种是字面值创建,一种是 new 创建,这两者存储的内存地址是不一样的。
如果是字面值创建的方式,如 String a="a",JVM会先去字符串常量池中寻找有没有“a”这个字符串,若有,则将其地址给 a;若没有,则先在常量池里创建“a”,然后再把地址给a;而通过 new a = new String("a")的方式创建对象,则是在堆中创建“a”对象,a 指向这个对象。
当字符串进行拼接时,如果是字面值进行拼接,在编译阶段会进行优化,直接变成字符串”abc“。
当字符串变量相加时,因被final修饰,字符串不能修改,会 先生成StringBuilder对象,通过append()方法进行字符串拼接,在调用toString()方法形成新的字符串,所以s1可以理解为
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("a");
stringBuilder.append("b");
stringBuilder.append("c");
String s = stringBuilder.toString();