首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java中使用String(String)构造函数

在Java中使用String(String)构造函数
EN

Stack Overflow用户
提问于 2009-01-21 14:56:05
回答 6查看 37K关注 0票数 11

我在一些文章和书籍中读到,应该一直避免使用String s = new String("...");。我理解这是为什么,但是使用String(String)构造函数有什么用处吗?我不认为有,也看不到任何其他证据,但我想知道是否有人在如此社区知道用途。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-01-21 15:08:25

这是一篇好文章:String constructor considered useless turns out to be useful after all!

事实证明,这个构造函数至少在一种情况下是有用的。如果您曾经偷看过String的源代码,您将会看到它不仅有字符数组值和字符计数的字段,还有到字符串开头的偏移量的字段。这是因为String可以与其他String共享char数组值,这通常是调用substring()方法的结果。早在几年前,Java就因此受到了jwz的Java抨击:这种开销的唯一原因是,String.substring()可以返回共享相同值数组的字符串。这样做的代价是为每个字符串对象增加8个字节,这并不是净节省...抛开字节节省不谈,如果你有这样的代码: //假设这里有一个多兆字节的字符串string s= "0123456789012345678901234567890123456789";String s2 = s.substring(0,1);s= null;

现在您将拥有一个字符串s2,尽管它看起来是一个单字符字符串,但它包含了对在字符串s中创建的巨大字符数组的引用。这意味着该数组将不会被垃圾回收,即使我们显式地将字符串s置为空!解决这个问题的方法是使用前面提到的“无用”字符串构造函数,如下所示:

string s2 =新字符串(s.substring(0,1));如果旧数组大于字符串中的字符数,则此构造函数是否会将旧内容实际复制到新数组并不为人所知。这意味着旧的字符串内容将按预期进行垃圾收集。快乐快乐,快乐的joy,快乐的joy。

最后,Kat Marsen提出了这些观点,

首先,字符串常量永远不会被垃圾回收。其次,字符串常量是实例化的,这意味着它们在整个VM中共享。这节省了内存。但这并不总是你想要的。

字符串上的复制构造函数允许您从字符串文字创建私有字符串实例。这对于构造有意义的互斥对象非常有价值(出于同步的目的)。

票数 41
EN

Stack Overflow用户

发布于 2009-01-21 15:00:27

如果我没记错的话,唯一“有用”的情况是原始字符串是一个更大的后备数组的一部分。(例如,作为子串创建)。如果您只想保留较小的子字符串,并对较大的缓冲区进行垃圾回收,那么创建一个新字符串可能是有意义的。

票数 11
EN

Stack Overflow用户

发布于 2009-01-21 15:19:57

只是为了扩展一下Douglas's answer*,我可以给出一个明确的例子来说明我在哪里使用它。假设阅读一个有数千行的字典文件,每行只有一个单词。阅读这篇文章的最简单方法是使用BufferedReader.readLine()

不幸的是,默认情况下,readLine()分配80个字符的缓冲区作为预期的行长。这意味着它通常可以避免无意义的复制-并且浪费一点内存通常也不是太糟糕。但是,如果您在应用程序期间加载一个短词词典,您最终会永久浪费大量内存。我的“小应用程序”吸收了比它应该做的多得多的内存。

解决方案是改变这一点:

代码语言:javascript
复制
String word = reader.readLine();

如下所示:

代码语言:javascript
复制
String word = new String(reader.readLine());

..。当然,还有评论!

*我不记得我是不是和道格拉斯一起工作,或者只是巧合,他回答了这个问题。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/465627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档