既然题目里就提到了JVM,那么首先必然要奉上两张图。
HotSpot JVM内存模型已经是老生常谈的知识了,所以这里也就不再赘述。直接说String。
在String类的JavaDoc开头,就有这样一句话:
Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.
也就是说,String是不可变类。与它类似,基本类型的包装类也都是不可变类。字符串是常量,一旦初始化之后就不能更改。如果需要可变的字符串,就要借助StringBuilder和StringBuffer了。
为什么说String是不可变的?因为在它的内部是用一个final char数组来存储的。
private final char value[];
String s1 = "LittleMagic";
String s2 = "LittleMagic";
String s3 = new String("LittleMagic");
String s4 = s3.intern();
String s5 = "Little" + "Magic";
String s6 = "LittleMagic2";
String s7 = s2 + 2;
System.out.println(s1 == s2); // true
System.out.println(s2 == s3); // false
System.out.println(s2 == s4); // true
System.out.println(s2 == s5); // true
System.out.println(s6 == s7); // false
这段代码的字节码如下。
0: ldc #2 // String LittleMagic
2: astore_1
3: ldc #2 // String LittleMagic
5: astore_2
6: new #3 // class java/lang/String
9: dup
10: ldc #2 // String LittleMagic
12: invokespecial #4 // Method java/lang/String."":(Ljava/lang/String;)V
15: astore_3
16: aload_3
17: invokevirtual #5 // Method java/lang/String.intern:()Ljava/lang/String;
20: astore 4
22: ldc #2 // String LittleMagic
24: astore 5
26: ldc #6 // String LittleMagic2
28: astore 6
30: new #7 // class java/lang/StringBuilder
33: dup
34: invokespecial #8 // Method java/lang/StringBuilder."":()V
37: aload_2
38: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: iconst_2
42: invokevirtual #10 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
45: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
48: astore 7
50: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;
53: aload_1
54: aload_2
.................
下面来逐个分析。
A pool of strings, initially empty, is maintained privately by the
class {@code String}.
When the intern method is invoked, if the pool already contains a string equal to this {@code String} object as determined by the {@link #equals(Object)} method, then the string from the pool is returned. Otherwise, this {@code String} object is added to the pool and a reference to this {@code String} object is returned.
意思就是,如果字符串常量池中已经存在一个字面量上相等(用String.equals()方法判定)的字符串,就返回常量池中的字符串。否则,就将这个字符串加入常量池,并返回它的引用。这样理解,s2与s4相等就是自然的了。
页面更新:2024-04-11
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号