看看这个测试
String s1 = "1234";
String s2 = "123";
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] value1 = (char[]) field.get(s1);
char[] value2 = (char[]) field.get(s2);
System.out.println(value1 == value2);
它打印出来false
,这意味着 JVM 为 s1 和 s2 保存了两个不同的 char 数组。谁能解释为什么 s1 和 s2 不能共享同一个字符数组?似乎 java.lang.String 是为内容共享而设计的,不是吗?
注意:我不了解所有 JVM。这是 Oracle 的 Java HotSpot(TM) 客户端 VM 22.1-b02 (JRE 1.7)。
更新
另一方面,如果部分共享很少见(似乎仅适用于由 String.substring 创建的字符串),那么为什么所有字符串都应该具有int count
和int offset
字段?它是 8 个无用字节。而这不仅是大小,也是创作速度。对象越大,初始化的时间就越长。这是一个测试
long t0 = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
new String("xxxxxxxxxxxxx");
}
System.out.println(System.currentTimeMillis() - t0);
大约需要 200 毫秒。如果我使用这个类
class String2 {
char[] value;
String2(String2 s) {
value = s.value;
}
}
大约需要 140 毫秒。