注意:我不是在比较字符是否相等。因为我知道如何使用String.equals()方法。这个问题是关于String引用的。
当我在备考OCA考试时,开始学习String类以及其不可变性等属性。根据我的了解和阅读,字符串池是Java创建字符串时存储对象的地方,如果新创建一个包含相同值的字符串,它会引用字符串池中的字符串,除非我们使用new关键字,这将创建一个新的引用,即使两个字符串包含相同的值。
例如:
String a = "foo";
String b = "foo";
String c = new String("foo");
boolean ab = (a == b); // This return true
boolean ac = (a == c); // This return false
清楚地讲,这段代码的作用是:第一行代码创建了一个
String a = "foo"
并将其存储在字符串池中,第二行代码将创建String b
并引用到"foo"
,因为它已经存在于字符串池中。但是第三行代码无论该字符串是否已经存在,都会创建该字符串的新引用。下面是一个小的图形示例:
问题出现在以下代码行。当通过连接创建字符串时,Java是否有所不同,或者简单的==比较器具有另一种行为?例子 A:
String a = "hello" + " world!";
String b = "hello world!";
boolean compare = (a == b); // This return true
示例 B:
a = "hello";
b = "hel" + "lo";
compare = (a == b); // This return true
示例C:
a = "Bye";
a += " bye!";
b = "Bye bye!";
compare = (a == b); // This return false
观看代码运行:(http://ideone.com/fdk6KL)
发生了什么?
编辑
修复示例B中的错误:
b ='hel'+'lo'
添加有关问题的说明。这不是一个比较问题,因为我知道如何使用
String.equals()
,问题在于字符串池的引用。
"Some Text" + i + "."
。您认为这需要在字符串池中创建成千上万个条目吗? - D MString a = "foo"
的说法是不正确的。该行仅创建了对字符串的引用(指向变量),而字符串本身已经存在于字符串池中,在类初始化时被放置在那里。 - Lew BlochString
实例的表达式,例如调用new String(...)
或连接操作,都会创建一个新的、非内部化的String
实例。 "字符串字面量 - 或者更一般地说,是常量表达式(§15.28)的值的字符串 - 被"内部化"以共享唯一实例,使用方法String.intern
。" http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.5 否则必须显式调用intern
。阅读精细手册。 - Lew Bloch