Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,它们可以储存和操作字符串。其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的。而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer要高。
String对象的intern方法会得到字符串对象在常量池中对应的版本的引用(如果常量池中有一个字符串与String对象的equals结果是true),如果常量池中没有对应的字符串,则该字符串将被添加到常量池中,然后返回常量池中字符串的引用;
看下面这段代码
/**
* Created by lujie on 2018/9/5.
*/
public class StringEqualTest {
public static void main(String[] args) {
String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program";
String s4 = "ming";
String s5 = "Program" + "ming";
String s6 = s3 + s4;
System.out.println(s1 == s2); //false
System.out.println(s1 == s5); //true
System.out.println(s1 == s6); //false
System.out.println(s1 == s6.intern()); //true
System.out.println(s2 == s2.intern()); //false
}
}
字符串的+操作其本质是创建了StringBuilder对象进行append操作,然后将拼接后的StringBuilder对象用toString方法处理成String对象。
通过查看字节码可以得知。
StringTest.java
/**
* Created by lujie on 2018/9/5.
*/
public class StringTest {
public static void main(String[] args) {
String a = "Hello";
String b = "World";
String c = a + b ;
String d = "Hello" + "World";
}
}
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=5, args_size=1
0: ldc #2 // String Hello
2: astore_1
3: ldc #3 // String World
5: astore_2
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: ldc #8 // String HelloWorld
27: astore 4
29: return
LineNumberTable:
line 8: 0
line 9: 3
line 10: 6
line 11: 25
line 12: 29
LocalVariableTable:
Start Length Slot Name Signature
0 30 0 args [Ljava/lang/String;
3 27 1 a Ljava/lang/String;
6 24 2 b Ljava/lang/String;
25 5 3 c Ljava/lang/String;
29 1 4 d Ljava/lang/String;
}