String中的 “+” 号拼接字符串的理解
1、String字符串在内存中分配
String s = new String(“Hello world”)可能创建两个对象也可能创建一个对象。如果方法区中有“Hello world”字符串常量的话,则仅仅在堆中创建一个对象。如果方法区中没有“Hello world”对象,则堆上和方法区中都需要创建对象。
String s1 = new String("Hello world");
String s2 = "Hello world";
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true
2、字符串常量拼接
String str3 = "Hello"+" word";
String str4 = "Hello word";
System.out.println(str3 == str4); //true
上面是字符串常量拼接的例子:在编译时,JVM编译器对字符串做了优化,str3就被优化成“Hello word”,str3和str4指向字符串常量池同一个字符串常量,所以==比较为true
3、字符串常量+字符串变量、字符串变量之间的拼接
String str5 = "Hello";
String str6 = " word";
String str7 = "Hello word";
String str8 = str5+" word";
System.out.println(str7 == str8); //false
String通过+号来拼接字符串的时候,如果有字符串变量参与,实际上底层会转成通过StringBuilder的append( )方法来实现,大致过程如下
StringBuilder sb = new StringBuilder( );
sb.append(str5);
sb.append(" word");
str8 = sb.toString();
StringBuilder 的 toString( )方法底层new了一个String对象,所以str8在堆内存中重新开辟了新空间,而str7指向常量池,所以str7 == str8为false。
变量字符串拼接和常量字符串拼接结果是不一样的。因为变量字符串拼接是先开辟空间,然后再拼接。