为什么私有包 String constructor (int, int, char[]) 被移除了?

Why the private package String constructor (int, int, char[]) has been removed?

在 Java6 中,有一个包私有构造函数 return 一个偏移量被改变的新字符串。

643     // Package private constructor which shares value array for speed.
644     String(int offset, int count, char value[]) {
645         this.value = value;
646         this.offset = offset;
647         this.count = count;
648     }

它已在 Java 7 中标记为已弃用,并在 Java 8 中被删除。我依赖于一些 API 反复调用 subSequence,直到我遇到了性能问题。

深入研究代码,我看到 subSequence 在 Java 6 中使用了这个构造函数。但就目前而言,它使用另一个复制底层数组并从所需位置开始并结束的构造函数偏移量,从而使其成为 O(n) 的 O(1) 操作。

将有问题的调用替换为 subSequence 将性能提高了 10 倍。

我想知道为什么要进行这样的更改。我唯一想到的是它可能会造成潜在的内存泄漏,例如:

String veryLargeString = ....;
String target = veryLargeString.substring(0, 10);
//assume I don't need anymore veryLargeString at this point

那时底层的 char 数组不能被 GC,因为它仍然被目标 String 使用。因此你在内存中有一个大数组,但你只需要它的前 10 个值。

这是唯一好的用例还是有其他原因导致此构造函数被删除?

是的,Stringchanged significantly in Java 7 update 6 - 现在单独的 String 对象从不共享基础 char[]。这绝对是一个权衡:

  • 字符串不再需要维护偏移量和长度(每个实例节省两个字段;不是很多,但它适用于 每个 字符串...)
  • 一个小字符串无法让一个巨大的 char[] 存活下来(根据您的 post)
  • ...但以前便宜的操作现在最终会创建副本

在某些用例中,以前的代码会工作得更好 - 在其他用例中,新代码会工作得更好。不幸的是,听起来你在第一个营地。我无法想象这个决定是轻易做出的,但是 - 我怀疑针对不同的常见工作负载进行了大量测试。