java中的字符串空构造函数

我正在查看String API,突然我遇到一个String空构造函数,即我们可以使用String s = new String()构造一个空的String对象

我不知道有什么用吗?

当然…..

String s = new String();

将在堆上创建一个非文字String对象 ,这将被垃圾收集。

在哪里

String s = "" ;

将创建一个String Literal 。 如果可以通过默认加载​​器访问它,那么它将不会被垃圾收集。

请参阅下面的链接以查询我提出的问题。 这可能与您的问题没有直接关系,但它肯定会帮助您牢牢掌握这个概念。

String Literal Pool是String对象或对象集合的引用的集合

它创建了空字符串,似乎有一些限制使用。

如果您将通过连接构建String ,并且不使用例如StringBuiler ,则您的代码可以作为以下之一开始。

 String result = new String(); String result = ""; String result = "first part of string"; // ... result += "append to the result"; 

前两个等同,你应该更喜欢用""初始化,因为这可以利用字符串实习 。

小例子……字符串可以被垃圾收集

 System.out.println(1 + new String() + 2); 

代替

 System.out.println(1 + "" + 2); 

根据文档,此构造函数创建一个空序列。

 public String() Initializes a newly created String object so that it represents an empty character sequence. Note that use of this constructor is unnecessary since Strings are immutable. 

如果你想要一个空序列,那就有意义了。

但通常情况下,在对其进行更改之前不必使用空构造函数,因为您没有更改String。 实际上,当您使用运算符+ =进行更改时,您正在创建另一个不可变的String,而不是更改一个。

检查有关此主题的问题: String对象如何工作(如不可变对象)?

一些背景优先

因为Java中的字符串是不可变的,所以它们也是“实例化” – 这意味着加载的类中的所有字符串文字都保存在池中,因此通常一次只有一个内存中每个唯一字符串文字的实例。 它是flyweight模式的应用程序,类似的池也保留用于Integer和其他原始包装器对象(但仅限于有限数量的小值)。

由于这种机制,通常可以对字符串文字进行身份比较(甚至来自不同的类)(尽管在比较字符串时应始终使用equals方法以确保安全性和一致性):

 System.out.println("hello" == "hello"); // true 

现在,如果使用默认字符串构造函数,则会得到一个空字符串的实例,但它是一个实例,如JavaDoc中所述:

初始化新创建的String对象,使其表示空字符序列。 请注意,由于字符串是不可变的,因此不必使用此构造函数。

这样的新实例与实习的空字符串不同,导致:

 System.out.println(new String() == ""); // false 

但正如我所说,只有字符串文字会自动实现 – 这意味着StringBuilders手动创建的字符串,字符数组等等都不会被实现。 您可以使用String.intern()方法手动将此类字符串放入池中。

现在来看一些真实情况

确实这一切都很好,但我仍然没有回答为什么这个构造函数存在 。 好吧,Java字符串只是char数组的智能包装器,一些不同的字符串对象可以共享它们的内部数组。

如果我创建一个非常长的字符串(例如通过从流中读取),那么这个实例不会被实现(如上所述),因此在引用它的变量超出范围之后它将被垃圾收集。 但如果这样做:

 String longString = readVeryLongString(); String shortString = longString.subString(0, 10); 

…然后新的shortString不会从longString复制前10个字符并将它们放入自己的新char数组中。 不,它将引用原始数组,仅使用前10个字符。

现在,如果shortString变量具有更长的生命周期(例如放入某个静态上下文),那么底层char数组将不会被垃圾收集 (即使原始的longString变量已经超出范围)。 这是如何在Java中创建内存泄漏的方法之一。

现在,默认的字符串构造函数来拯救! 如果我将上面的代码更改为:

 String longString = readVeryLongString(); String shortString = new String(longString.subString(0, 10)); 

…然后shortString将是一个新的字符串实例,它通过仅复制subString方法返回的原始字符串中的10个必需字符来创建新的内部char数组。


一篇很好的文章说明了这个主题

http://illya-keeplearning.blogspot.cz/2009/03/java-string-internals.html

要创建一个空字符串,请将默认构造函数调用为String s new String();

将创建一个没有字符的String实例。