代码之家  ›  专栏  ›  技术社区  ›  Vasil

Java中的字符串COUNT和+运算符有区别吗?[复制品]

  •  18
  • Vasil  · 技术社区  · 15 年前

    复制品

    java String concatenation

    我很好奇这两者有什么不同。

    我对字符串池的理解是:

    这将在字符串池中创建3个字符串对象,其中2个所有引用都将丢失。

    String mystr = "str";
    mystr += "end";
    

    这不也会在字符串池中创建3个对象吗?

    String mystr = "str";
    mystr = mystr.concat("end")
    

    我知道stringbuilder和stringbuffer在需要进行大量的concation时,在内存使用方面效率更高。我只是好奇+运算符和concat在内存使用方面是否有区别。

    4 回复  |  直到 15 年前
        1
  •  30
  •   Community uzul    7 年前

    在这个特殊的情况下没有区别; 然而,它们在总体上并不相同。

    str1 += str2 相当于执行以下操作:

    str1 = new StringBuilder().append(str1).append(str2).toString();
    

    为了向自己证明这一点,只需制作一个简单的方法,它包含两个字符串 += 是第一个字符串到第二个字符串,然后检查反汇编字节码。

    相比之下, str1.concat(str2) 只需创建一个新字符串 str1 str2 ,这对于少量的连接字符串来说成本较低(但会输给第一个具有较大数字的方法)。

    另外,如果 STR1 为空,请注意 str1.浓度(str2) 抛出一个npe,但是 “=” 会简单地对待 STR1 好像它是空的,没有抛出异常。(也就是说,它产生与 STR2 . 如果 STR2 如果,说“foo”,你会得到“nullfoo”。)


    更新: this StackOverflow question ,几乎是一样的。

        2
  •  7
  •   Alan Moore Chris Ballance    15 年前

    两者之间的重要区别 += concat() 不是性能,而是语义。 小精灵 只接受字符串参数,但是 + (或) += )会接受的 任何东西 . 如果非字符串操作数是对象,则通过调用 toString() 在它上;原语将被转换,就像通过调用相关包装类中的适当方法一样,例如, Integer.toString(theInt) ;空引用变成字符串 "null" .

    实际上,我不知道为什么 小精灵 甚至存在。人们看到它列在api文档中,并认为它存在是有原因的——性能是最明显的原因。但这是一个危险的问题;如果性能确实是一个问题,那么您应该使用stringbuilder,正如john链接到的线程中所讨论的那样。否则, + += 更方便。

    编辑:关于“在字符串池中创建对象”的问题,我认为您误解了字符串池是什么。在运行时,实际的字符序列“str”和“end”将存储在一个专用的数据结构中,并且无论您在何处看到文本 "str" "end" 在源代码中,字节码将真正包含对该数据结构中相应项的引用。

    实际上,字符串池是在加载类时填充的,而不是在运行包含字符串文本的代码时填充的。这意味着每个片段只创建一个对象:连接的结果。(在幕后也有一些对象创建,这对每种技术都有点不同,但性能影响不值得担心。)

        3
  •  1
  •   brian-brazil    15 年前

    除非concat的参数是空字符串,否则

    String mystr = "str";
    mystr = mystr.concat("end")
    

    也将创建3个字符串。

    更多信息: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html

        4
  •  1
  •   Michael Borgwardt    15 年前

    我对弦乐池的理解 是这样的:

    你似乎对那个词有误解。不存在“字符串池”这样的东西——你使用它的方式,看起来你只是指堆中的所有字符串对象。那里 runtime constant pool 它包含编译时字符串常量和从 String.intern()