【问题标题】:java string concatenation and interningjava字符串连接和实习
【发布时间】:2017-12-23 05:53:57
【问题描述】:

问题 1

String a1 = "I Love" + " Java";
String a2 = "I Love " + "Java";
System.out.println( a1 == a2 ); // true

String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
System.out.println( b1 == b2 ); // false

在第一种情况下,我理解它是两个字符串文字的连接,因此结果“I Love Java”将被实习,结果为真。但是,我不确定第二种情况。

问题 2

String a1 = "I Love" + " Java"; // line 1
String a2 = "I Love " + "Java"; // line 2

String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
String b3 = b1.intern();
System.out.println( b1 == b3 ); // false

上面返回false,但是如果我注释掉第1行和第2行,它返回true。这是为什么呢?

【问题讨论】:

  • 我们从未真正使用 == 运算符比较字符串,而是使用 .equals 方法
  • @JoeyPinto OP 使用 == 了解 Java 内部结构,发现看起来很奇怪但有合理解释的行为。

标签: java string-concatenation string-interning


【解决方案1】:

您问题的第一部分很简单:Java 编译器将多个字符串文字的串联视为单个字符串文字,即

"I Love" + " Java"

"I Love Java"

是两个相同的字符串字面量,它们会被正确地嵌入。

同样的实习行为适用于对字符串的+=操作,所以b1b2实际上是在运行时构造的。

第二部分比较棘手。回想一下b1.intern() 可能会返回b1 或其他一些与它相等的String 对象。当您保留a1a2 时,您会从对b1.intern() 的调用中获得a1。当您注释掉a1a2 时,没有要返回的现有副本,因此b1.intern() 将返回b1 本身。

【讨论】:

    【解决方案2】:

    来自实习生()文档

    所有文字字符串和字符串值的常量表达式都被实习。字符串文字在 Java™ 语言规范的第 3.10.5 节中定义。

    来自JLS 3.10.5

    • 由常量表达式(第 15.28 节)计算的字符串在 编译时间,然后将它们视为文字。
      • 在运行时通过连接计算的字符串是新创建的,并且 因此与众不同。

    您的字符串 b1 实际上没有被实习。因此有区别。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 2011-02-11
      • 2011-04-02
      • 1970-01-01
      相关资源
      最近更新 更多