您可能会遇到的唯一一个地方think你要new String(String)
是强制内部字符数组的不同副本,如
small=new String(huge.substring(10,20))
然而,不幸的是,这种行为没有记录并且依赖于实现。
当我将大文件(有些高达 20 MiB)读取到字符串中并在事后将其雕刻成行时,我已经被这个问题困扰了。我最终得到了引用 char[] 的行的所有字符串,该行由整个文件组成。不幸的是,无意中保留了对整个数组的引用,因为我保留的几行时间比处理文件的时间更长 - 我被迫使用new String()
解决这个问题,因为处理 20,000 个文件很快就会消耗大量 RAM。
唯一与实现无关的方法是:
small=new String(huge.substring(10,20).toCharArray());
不幸的是,这必须复制数组两次,一次是toCharArray()
一次在 String 构造函数中。
需要有一种记录在案的方法,通过复制现有字符串的字符来获取新字符串;或文档String(String)
需要改进以使其更加明确(那里有一个暗示,但它相当模糊且易于解释)。
假设文档没有说明的陷阱
为了回应不断出现的评论,请观察 Apache Harmony 的实现new String()
was:
public String(String string) {
value = string.value;
offset = string.offset;
count = string.count;
}
没错,那里没有底层数组的副本。然而,它仍然符合 (Java 7) String 文档,因为它:
初始化一个新创建的 String 对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。除非需要原始的显式副本,否则不需要使用此构造函数,因为字符串是不可变的。
显着的部分是“论证的副本string”;它没有说“参数字符串的副本和支持该字符串的底层字符数组”。
请小心您的编程文档并不是one 执行.