当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在Java中使用String(String)构造函数》经验,为你挑选了3个好方法。

我读过文章和书籍,String s = new String("...");应该尽可能避免使用.我明白为什么会这样,但是使用String(String)构造函数有什么用处吗?我不认为有,也没有看到任何其他证据,但我想知道SO社区中是否有人知道有用.


确切重复: java中表达新字符串的目的是什么?



1> mmcdole..:

这是一篇很好的文章:毕竟认为无用的字符串构造函数毕竟是有用的!

事实证明,这个构造函数实际上至少在一种情况下是有用的.如果你曾经看过String源代码,你会发现它不仅包含char数组值和字符数的字段,而且还包含字符串开头的偏移量.这样,Strings可以与其他字符串共享char数组值,通常是调用substring()方法之一.Java在几年前的jwz'Java咆哮中受到了严厉的批评:

这种开销的唯一原因是String.substring()可以返回共享相同值数组的字符串.这样做是为了向每个String对象添加8个字节而不是净节省......

除了节省字节,如果你有这样的代码:

// imagine a multi-megabyte string here  
String s = "0123456789012345678901234567890123456789";  
String s2 = s.substring(0, 1);  
s = null;

你现在将拥有一个String s2,虽然它似乎是一个单字符的字符串,但它拥有对String中创建的巨大字符数组的引用.这意味着数组不会被垃圾收集,即使我们已经明确地删除了String!

解决这个问题的方法是使用我们之前提到的"无用的"String构造函数,如下所示:

String s2 = new String(s.substring(0, 1));  

众所周知,如果旧数组大于字符串中的字符数,则此构造函数实际上将旧内容复制到新数组.这意味着旧的String内容将按预期进行垃圾回收.快乐幸福快乐的喜悦.

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

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

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


请注意,这与Java 7(我认为)之后不再相关,其中`String.substring()`的实现已更改以避免此问题.

2> Douglas Leed..:

如果我没记错的话,唯一"有用"的情况是原始字符串是更大的后备数组的一部分.(例如,创建为子字符串).如果你只想保留小的子串并且垃圾收集大缓冲区,那么创建一个新的String可能是有意义的.



3> Jon Skeet..:

为了扩展道格拉斯的答案*,我可以给出一个我用过它的确凿例子.考虑阅读一个包含数千行的字典文件,每个行只有一个单词.阅读本文的最简单方法是使用BufferedReader.readLine().

不幸的是,readLine()默认情况下,分配一个80个字符的缓冲区作为预期的行长度.这意味着它通常可以避免无意义的复制 - 而且浪费的内存通常不会太糟糕.但是,如果您在应用程序的持续时间内加载了一个短词字典,那么最终会浪费大量内存.我的"小应用程序"吸取的内存远远超过应有的内存.

解决方案是改变这个:

String word = reader.readLine();

进入这个:

String word = new String(reader.readLine());

......当然还有评论!

* 我不记得在实际出现这个问题时我是否与道格拉斯合作,或者他回答这个问题是否巧合.

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有