【问题标题】:Why trim() give me String Constant Pool reference?为什么 trim() 给我字符串常量池参考?
【发布时间】:2017-06-20 11:19:31
【问题描述】:

我正在探索字符串常量池和堆内存。

if("String".trim() == "String")
    System.out.println("Equal");
else
    System.out.println("Not Equal"); 

输出

Equal

如果我在修剪之前在字符串中添加一个空格,它将给出不相等的输出

if("String  ".trim() == "String")
    System.out.println("Equal");
else
    System.out.println("Not Equal");

输出

Not Equal

你能解释一下上面的场景吗?

以及如何查看堆内存和字符串常量池?

【问题讨论】:

  • 因为如果 trim() 不更改字符串,它只会返回 this 即原始字符串对象本身。
  • 因为字符串是不可变的
  • 无关:不要养成使用 { 大括号 } 让 if/then/else 块没有的习惯。始终使用 { 大括号 }。
  • @nafas “平等”是在返回的字符串上完成的(如果需要,也就是新的字符串或本身)
  • @nafas 这是正确的,但在这里并不重要。

标签: java string compare


【解决方案1】:

String.trim() 状态的 (Java 8) javadocs

返回:一个字符串,其值为该字符串,任何前导和尾随空格都已删除,如果没有前导或尾随空格,则为该字符串

由于"String" 没有前导或尾随空格,trim() 将返回"String" 对象。

另一方面,"String " 有尾随空格,因此返回不同的 String 对象1

BTW:它不叫“字符串常量池”。所有字符串都是恒定的(不可变的)。您可能正在谈论作为编译时常量表达式评估结果的所有字符串。但是,字符串池也可以包含由String.intern() 调用动态创建的字符串添加的字符串。正确的说法是“字符串池”。


1 - 碰巧这个对象与代表"String" 的对象不同。但是,仔细阅读 javadoc 会发现规范并不要求这种情况。在不同的(假设的)Java 版本中,trim() 方法可以返回 "String" 对象并且仍然符合规范。

【讨论】:

    【解决方案2】:

    trim()方法可以返回相同的实例或者一个全新创建的字符串对象,你可以在方法的源代码中验证:

     return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
    

    所以这取决于这个条件是否满足

    ((st > 0) || (len < value.length))
    

    现在当你这样做时:"String".trim() == "String" 条件不满足,所以你将比较文字“String”的引用

    在左侧选项中,创建了一个新对象,使用 == 进行比较返回 false....

    【讨论】:

      【解决方案3】:

      第二个例子显示“不等于”,因为,

      方法trim() 返回此字符串的副本,删除了前导和尾随空格,或者如果该字符串没有前导或尾随空格,则返回此字符串。

      文案很重要。

      【讨论】:

      • 实际上,javadoc 根本没有使用“copy”这个词。我不知道你从哪里得到你引用的文字,但它不是官方文档......而且它(IMO)具有误导性。
      • @Tom,复制意味着它是一个具有新地址的新对象。 “文案很重要”怎么不重要?
      • @StephenC 我在单词 'trim()' 下链接了文档
      • 啊……我明白了。您正在引用 >>oldtrim() 返回副本的情况!
      【解决方案4】:

      字符串是对象,因此将字符串与 == 进行比较不是正确的选择。 Trim 返回一个字符串,然后您需要使用等号将其与另一个字符串进行比较,即使该字符串未包装到变量中。尝试使用:

      System.out.println("这是一个字符串".trim());

      String test = "这是一个字符串"; System.out.println(test.trim());

      两者都会给出相同的答案:“这是一个字符串”

      你应该使用你的情况:

      "string".trim().equals("string")
      

      这会给你正确的答案。

      【讨论】:

      • 这没有回答问题。
      猜你喜欢
      • 2011-07-02
      • 1970-01-01
      • 2014-06-08
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-14
      • 2011-07-24
      相关资源
      最近更新 更多