【问题标题】:How does String concatenation work in terms of the String Pool? [duplicate]就字符串池而言,字符串连接如何工作? [复制]
【发布时间】:2021-05-05 05:19:34
【问题描述】:
13: String a = "";
14: a += 2;
15: a += 'c';
16: a += false; 
17: if ( a == "2cfalse") System.out.println("==");
18: if ( a.equals("2cfalse")) System.out.println("equals");

输出: equals

如果我错了,请纠正我...

在第 13 行创建了一个新的String 对象,并且引用存储在a。 (a = "")

在第 14 行创建了一个新的String 对象,并且引用存储在a 中。之前的 String 对象符合垃圾回收 (GC) 条件。 (a = "2c")

在第 15 行创建了一个新的 String 对象,并且引用存储在 a 中。之前的 String 对象符合垃圾回收 (GC) 条件。 (a = "2cfalse")。

现在,String pool2cfalse 文字组成。因此,在第 17 行,不应将 a == "2cfalse" 评估为 true,因为它们都指向内存中的同一个对象?

但是,程序输出只是==。我哪里做错了?谁能给我解释一下...

【问题讨论】:

  • 如果您担心这些问题,请使用StringBuilder(除非这是家庭作业并且您需要解释)。
  • 是的,我需要一个解释...
  • 你已经离开了这些值,即第 14 行之后的字符串是"2",第 15 行之后是"2c"

标签: java string garbage-collection concatenation string-pool


【解决方案1】:

"2cfalse" 仅添加到第 17 行的字符串池中,当您将 a 与文字 "2cfalse" 进行比较时。

a 在第 17 行之前引用的实例未添加到字符串池中,因此它与 "2cfalse" 文字的实例不同。

如果您在第 17 行之前添加对 a.intern () 的调用,则 a 引用的实例将被添加到池中(因为它尚未在池中),并且第 17 行中的条件将评估为真。

如果一个等于"2cfalse"String 在调用a.intern() 之前已经在池中,则必须将其分配回a(即a = a.intern();),以便a引用存储在池中的实例。

String a = "";
a += 2;
a += 'c';
a += false; 
a.intern (); // or a = a.intern(); in case the pool already contains "2cfalse"
if ( a == "2cfalse") System.out.println("==");
if ( a.equals("2cfalse")) System.out.println("equals");

输出:

==
equals

【讨论】:

  • 非常感谢您的回答。你能解释一下为什么第 17 行之前的实例没有被添加到字符串池中吗?
  • @S.Tiss 并非每个 String 实例都会自动添加到池中。我相信只有字符串文字的实例和调用intern() 的实例才会添加到池中。
  • @S.Tiss 只有文字会被 JVM 添加到字符串池中,其他字符串可以通过调用 intern() 添加。但是请注意,如果您 constuct 像使用 "2cfalse" 那样处理的字符串,即使文字已经在字符串池中,您的 == 案例也会失败。这是因为默认情况下新的字符串对象不在池中,即使它们与池中的值相同。
  • 为了清楚起见,我要添加一条额外的信息:如果在调用 a.intern()"2cfalse" 已经在池中,则您需要分配返回的字符串,否则 == 仍然会失败。在上面的情况下,它可以工作,因为实例在通过文字检索它之前被放入池中。
  • 编译时常量被添加到池中。因此,("" + 2 + 'c' + false) == "2cfalse" 将评估为 true。但是,如果您以这种方式编写整个表达式,它将在编译时被编译时常量 true 替换,因此仍然不会将任何字符串添加到池中。如果您写String s = "" + 2 + 'c' + false; boolean b = s == "2cfalse";b 将是true,并且字符串添加到池中,但这只是表明对象标识 比池更重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
  • 2015-09-01
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多