如果在字符串常量池区域中创建(或已存在)相同的字符串文字,那么在堆中创建重复的String对象有什么好处?

时间:2015-11-05 17:22:37

标签: java string

String str = new String(“my literal”);

在上面的语句中,将创建两个对象,一个在字符串常量池中作为字符串文字“my literal”(如果字符串池中不存在),另一个在堆区域中作为对象字符串(“my literal” “)

问题1我知道将字符串文字放在字符串池区域中的好处但是我无法想到在堆中创建重复对象的好处吗?

Q2-当我通过流链接读取一些堆栈时:如果使用新的String("我的文字")几乎总是坏的,因为你将在String常量池上创建2个字符串,另一个在堆具有相同的值,那么我的问题是为什么Java在堆中创建重复的对象?为什么java只是忽略在堆中创建?

1 个答案:

答案 0 :(得分:5)

使用文字字符串调用String(String)构造函数几乎没有任何好处。 曾经是使用不同的字符串表达式调用String(String)构造函数的重要好处。

文字已经是String,String对象是不可变的。更一般地说,对于传递给String(String)构造函数的任何 String表达式,构造函数通常是不必要的,因为参数已经是不可变的String。

从String(String)构造函数文档:

  

public String(String original)

     

初始化一个新创建的String对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。除非需要显式的原始副本,否则不必使用此构造函数,因为字符串是不可变的。

对于旧版本的Java(1.7.0_06之前),String(String)构造函数更有用。 String.substring()创建的字符串可以引用较大的原始字符串,并防止它被垃圾收集。 String(String)构造函数将绑定切割为较大的String。

你问:

  

问题1:......在堆中创建重复对象的好处是什么?

通常没有。但是,如果您在对象标识很重要的上下文中使用String对象,则可能需要另一个对象。例如:

  • 您正在使用String对象作为IdentityHashMap中的键,并且只希望您自己的String对象匹配。
  • 您想要同步外部代码提供的字符串值。您不希望任何其他代码在同一个String对象上同步;它可能会导致意外干扰和死锁。 [此示例由@biziclop在下面的评论中提供。]
  

问题2:...为什么Java会在堆中创建重复的对象?

因为您明确要求new String("my literal")。如果您使用new运算符,则会获得一个新对象。