Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么字符串类有复制构造函数?_Java - Fatal编程技术网

Java 为什么字符串类有复制构造函数?

Java 为什么字符串类有复制构造函数?,java,Java,可能重复: 如果不可变类对象的副本与原始对象相同,那么为什么Java中的String类具有副本构造函数?这是一个错误还是这一实现背后有一个原因? Java文档中规定: /** * Initializes a newly created {@code String} object so that it represents * the same sequence of characters as the argument; in other words, the * newly creat

可能重复:

如果不可变类对象的副本与原始对象相同,那么为什么Java中的
String
类具有副本构造函数?这是一个错误还是这一实现背后有一个原因? Java文档中规定:

/**
 * Initializes a newly created {@code String} object so that it represents
 * the same sequence of characters as the argument; in other words, the
 * newly created string is a copy of the argument string. Unless an
 * explicit copy of {@code original} is needed, use of this constructor is
 * unnecessary since Strings are immutable.
 *
 * @param  original
 *         A {@code String}
 */
 public String(String original) {
 ....
 ....}

复制字符串的主要原因是“修剪行李”,也就是将底层字符数组修剪为只需要的字符

底层的字符数组可能太大,因为当您通过调用
substring
创建字符串时,字符数组可以在新字符串实例和源字符串实例之间共享;偏移点指向第一个字符,长度包括在内

我使用的表达式“trim The baggage”取自字符串复制构造函数的源代码:

  164       public String(String original) {
  165           int size = original.count;
  166           char[] originalValue = original.value;
  167           char[] v;
  168           if (originalValue.length > size) {
  169               // The array representing the String is bigger than the new
  170               // String itself.  Perhaps this constructor is being called
  171               // in order to trim the baggage, so make a copy of the array.
  172               int off = original.offset;
  173               v = Arrays.copyOfRange(originalValue, off, off+size);
  174           } else {
  175               // The array representing the String is the same
  176               // size as the String, so no point in making a copy.
  177               v = originalValue;
  178           }
  179           this.offset = 0;
  180           this.count = size;
  181           this.value = v;
这一点很多开发人员都忘记了,这一点很重要,因为一个小字符串可以防止对更大的字符数组进行垃圾处理。请参阅我已经指出的相关问题:。许多开发人员认为,java程序员使用的是C编码器所熟悉的这种老优化技巧,实际上弊大于利。我们中的许多人都知道这一点,因为我们被它咬了一口,并且必须查看Sun的源代码才能理解发生了什么


正如Marko指出的(参见下面的注释),在OpenJDK中,从Java7更新6开始,
substring
不再共享char数组,因此
String(String)
构造函数是无用的。但它仍然很快(事实上更快),而且由于这一变化没有传播到所有VM(可能不是所有客户),我建议保留这一最佳实践,在旧的行为证明它是正确的时候使用新字符串(子字符串)。

这不是“太本地化”,这是一个适用于以后发现它的人的好问题,有一个非常有用且信息丰富的答案。请参阅答案。请注意,上述类似问题的答案现在可能被视为部分过时了……并且从OpenJDK 7更新6起就消失了。通过
子字符串
修剪
等不再进行结构共享@Marko您能指出您提到的更新的来源吗?我没有意识到那个重要的变化。我已经把它放在书签里了,自从我从乔恩·斯基特那里了解到这件事以来,它就一直很受欢迎!