-1

考虑下面的代码

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编译器不实习字符串数组?

4

2 回答 2

4

原因是 aString是不可变的。您不能在不创建新实例的情况下对其进行更改。因此,尽可能安全地使用相同的实例来匹配字符串。字符串是常量;它们的值在创建后无法更改。

然而,阵列是另一回事。您可以更改数组,只需将新值分配给其中一个字段。

s1[0] = "testString3"

如果编译器将使用相同的实例,s1并且s2您将自动更改两个数组。这可能不是你想做的事情。这就是数组没有被实习的原因。

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

当涉及到比较字符串时,使用 equals 函数总是更好。无论如何,大多数实现都会首先检查引用相等性,然后再执行更昂贵的检查。

编辑:

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

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

字符串字面量总是引用 String 类的同一个实例。这是因为字符串字面量 - 或者更一般地说,作为常量表达式的值的字符串...... - 是“内部的”,以便使用 String.intern 方法共享唯一实例

说了这么多,还是请习惯使用equals字符串类的方法来检查字符串是否相等。该方法将利用字符串可能是相同的引用并在这种情况下非常快速地完成这一事实,然后执行更昂贵的长度和字符检查。使用这种方法总是更好。处理字符串的方式在 Java 的未来版本中可能会发生变化,也可能不会发生变化。使用这种equals方法,您是安全的。

于 2016-08-23T10:59:06.640 回答
-2

您不能只将字符串数组与== 之类的字符串进行比较。实习生只适用于字符串。如果你想比较字符串数组试试这个Java,如何比较字符串和字符串数组

于 2016-08-23T11:03:58.727 回答