我正在查看String API,突然间我遇到一个String空构造函数,即我们可以使用String s = new String()
我想知道它有用吗?
答案 0 :(得分:11)
Ofcourse .....
String s = new String();
将在堆上创建非文字String对象,将垃圾回收。
其中
String s = "" ;
将创建一个String Literal 。如果可以通过默认加载器访问,那么将不会垃圾收集。
请参阅以下链接,查询我提出的问题。这可能与您的问题没有直接关系,但它肯定会帮助您牢牢掌握这一概念。
Is String Literal Pool a collection of references to the String Object, Or a collection of Objects
答案 1 :(得分:4)
它创建了一个空字符串,似乎有一些限制用途。
如果您要通过连接构建String
,并且不使用例如StringBuiler
String result = new String();
String result = "";
String result = "first part of string";
// ...
result += "append to the result";
,您的代码可以作为以下之一开始。
""
前两个不等同于,您最好使用{{1}}进行初始化,因为这可以利用string interning。
答案 2 :(得分:2)
小例子......字符串可以被垃圾收集
System.out.println(1 + new String() + 2);
而不是
System.out.println(1 + "" + 2);
答案 3 :(得分:0)
根据文档,此构造函数创建一个空序列。
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。实际上,当您使用operator + =进行更改时,您正在创建另一个不可变的String,而不是更改一个。
检查此主题的问题:How do String objects work (like immutable objects)?
答案 4 :(得分:0)
因为Java中的字符串是不可变的,所以它们也是“实习” - 这意味着加载的类中的所有字符串文字都保存在池中,因此通常只有一个实例一次在内存中的唯一字符串文字。它是 flyweight模式的应用程序,类似的池也保留用于Integer和其他原始包装器对象(但仅限于有限数量的小值)。
由于这种机制,通常可以对字符串文字进行身份比较(甚至来自不同的类)(尽管在比较字符串时应始终使用equals
方法以确保安全性和一致性):
System.out.println("hello" == "hello"); // true
现在,如果您使用默认字符串构造函数,则会得到一个空字符串的实例,但它是一个 new 实例,如JavaDoc中所述:
初始化新创建的String对象,使其表示空字符序列。请注意,由于字符串是不可变的,因此不需要使用此构造函数。
这样的新实例与实习的空字符串不同,导致:
System.out.println(new String() == ""); // false
但正如我所说,只有字符串文字会自动实现 - 这意味着StringBuilders手动创建的字符串,char数组等等都不会被实现。您可以使用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个必需字符来创建新的内部字符数组。
一篇很好的文章说明了这个主题:
http://illya-keeplearning.blogspot.cz/2009/03/java-string-internals.html
答案 5 :(得分:-1)
创建一个空字符串,调用默认构造函数为 String s new String();
将创建一个没有字符的String实例。