为什么java编译器不插入数组?

时间:2016-08-23 10:56:08

标签: java arrays string-interning

考虑以下代码

String s1 = "testString";
String s2 = "testString";
if(s1 == s2)System.out.println("equals!");

它打印等于!,(我知道编译器的字符串实习)

String[] s1 = {"testString","teststring2"};
String[] s2 = {"testString","teststring2"};
if(s1 == s2)System.out.println("equals!");

但是上面的代码不起作用,为什么java编译器没有实习字符串数组?

2 个答案:

答案 0 :(得分:4)

原因是String是不可变的。您无法在不创建新实例的情况下对其进行更改。因此,尽可能使用相同的实例来匹配字符串是安全的。 Strings are constant; their values cannot be changed after they are created.

阵列是一个不同的故事。您可以更改数组,只需为其中一个字段分配新值。

s1[0] = "testString3"

如果编译器对s1s2使用相同的实例,则会自动更改两个数组。这可能不是你想要做的事情。这就是数组没有被实习的原因。

请注意,字符串实习可能有限制,具体取决于编译器,编译器可能会选择不实际执行某些字符串,具体取决于字符串的数量或字符串的长度。有一个内部字符串表由JVM选项+XX:StringTableSize=n控制,它确定用于存储实习字符串的字符串表的大小。

当归结为比较字符串时,使用equals函数总是更好。在执行更昂贵的检查之前,大多数实现首先检查引用相等性。

修改

所以实际上我声称内置字符串的存储空间增长似乎是错误的。 String.intern()方法的文档表明此函数将确保将字符串添加到唯一字符串池中。意味着这个游泳池无法满员。 @Holger写道,内部实现使用类似某种结构的哈希映射。这支持了这种说法。

因此,JVM将根据JLS §3.10.5将所有常量字符串存储在实际哈希表中。

  

字符串文字始终引用类String的相同实例。这是因为字符串文字 - 或者更一般地说,字符串是常量表达式的值... - 是" interned"以便使用String.intern

方法共享唯一的实例

所有这些,请仍然习惯字符串类的equals方法来检查字符串是否相等。该方法将利用这样的事实:在执行更昂贵的长度和字符检查之前,字符串可以是相同的参考并且在这种情况下非常快地完成。使用此方法总是更好。在未来的java版本中,字符串的处理方式可能会也可能不会改变。使用equals方法,您可以放心使用。

答案 1 :(得分:-2)

您无法将String数组与 == (如String)进行比较。实习生仅适用于String。如果要比较字符串数组,请尝试此Java, how to compare Strings with String Arrays