【问题标题】:Why String Pool behaves differently for literals and variables?为什么字符串池对于文字和变量的行为不同?
【发布时间】:2013-10-30 02:20:59
【问题描述】:

当我使用双引号将 2 个 strings(+) 运算符连接并与具有相同值的其他字符串文字进行比较时,结果为 true .. 但是当我连接时2个字符串变量和比较给出假?为什么会这样?

据我所知,当我们使用 (+) 运算符连接字符串时,JVM 会返回新的 StringBuilder(string...).toString(),它会在堆内存中创建一个新的 String 实例,并在 String pool 中创建一个引用。如果这是真的,它如何在一种情况下返回 true 而在另一种情况下返回 false?

第一种情况:

    String string1 = "wel";
    String string2 = "come";
    string1 = string1 + string2; //welcome

    String string3 = "welcome";
    System.out.println(string3 == string1); // this returns false but have same hashcode

第二种情况:

    String string4 = "wel" + "come";
    String string5 = "wel" + "come";
    System.out.println(string4 == string5); // this returns true

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 如果你连接非final String 变量,是的,你将有一个StringBuilder。如果你连接 String 文字,即不会。常量。
  • 总是将字符串与equals() 方法比较为string3.equals(string1);
  • “据我所知,当我们使用 (+) 运算符连接字符串时,JVM 返回 new StringBuilder(string...).toString() 会在堆内存中创建一个新的 String 实例”不是真的当您在源代码中连接字符串文字时,例如"wel" + "come"。这种连接是在编译时完成的,就像你写了"welcome"一样。 Suresh Atta's answer 中指出了这一点。
  • @user2511414 :我在这里使用 == 来检查两个值是否引用字符串池中的同一个实例,这是验证字符串池引用的唯一方法。目的是了解字符串池的工作原理。

标签: java string


【解决方案1】:

请关注cmets。

 string1 = string1 + string2; //StringBuilder(string...).toString() which creates a new instance in heap..

 String string3 = "welcome"; // It is not in heap. 

所以string3 == string1false

  String string4 = "wel" + "come"; //Evaluated at compile time

  String string5 = "wel" + "come"; //Evaluated at compile time and reffering to previous literal

所以string4 == string5true

【讨论】:

    【解决方案2】:

    据我所知,当我们使用 (+) 运算符连接字符串时,JVM 会返回 new StringBuilder(string...).toString(),它会在堆内存中创建一个新的 String 实例

    正确,除非两个操作数都是文字,在这种情况下,会在编译时创建一个字符串常量并进行池化。

    和字符串池中的一个引用。

    错误。字符串池中唯一的东西是字符串常量和String.intern() 返回值。

    如果是真的

    不是。

    如何在一种情况下返回真而在另一种情况下返回假?

    因为你的前提不正确。

    【讨论】:

    • “在编译时创建单个文字” - 这在挑剔的层面上是不准确的。 literal 是实际的语法特征 - 源代码中的 123"abc" 等表达式。在编译时,会在 constant pool 中创建一个条目——编译器不会生成源代码,因此它不会创建文字。 (我也不会说创建了 constant,因为它是变量的质量,而不是值的质量,值将是不可变的 - 所有 String 值都不管它们是否是文字.)
    • @millimoose 我同意“字符串文字”,并且在您发表评论前几分钟,我已经解决了这个问题。我不同意“恒定”。这就是为什么它被称为“常量池”。对于常数。有许多常量不是变量。字符串文字,首先:-|
    • 我承认的父母的部分是在语义上分裂头发的领域,我只是补充说来完成我的想法,而不是指出错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 2013-10-25
    • 2018-05-08
    • 1970-01-01
    • 2011-01-27
    相关资源
    最近更新 更多