为什么String类有复制构造函数? [英] Why String class has copy constructor?

查看:102
本文介绍了为什么String类有复制构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

如果不可变类对象副本等于原始副本那么为什么 String 类在Java有一个复制构造函数?这是一个错误还是这个实施背后的原因?
在Java文档中指定:

If immutable classes objects copies would be equal to the originals then why does the String class in Java have a copy constructor? Is it a mistake or there is a reason behind this implementation? In the Java docs it is specified that:

/**
 * 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) {
 ....
 ....}


推荐答案

主要原因复制字符串是为了修剪行李,即将基础字符数组修剪为只需要的东西。

The main reason to copy a string is to "trim the baggage", that is to trim the underlying char array to only what is necessary.

底层char数组可能主要是因为当你通过调用 substring 创建一个字符串时,char数组可以在新的字符串实例和源字符串实例之间共享;偏移量指向第一个字符,并包含长度。

The underlying char array can mainly be too big because when you create a string by calling substring, the char array can be shared between the new string instance and the source string instance; an offset points to the first character and the length is included.

我使用的表达式修剪行李取自字符串复制构造函数的源代码:

The expression I use, "trim the baggage", is taken from the source code of String copying constructor :

  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不是垃圾收集内存。许多开发人员认为,而不是Java设计师决定使用C编码器所熟悉的旧优化技巧,实际上弊大于利。我们中的许多人都知道它,因为我们被它咬了,并且必须查看Sun的源代码以了解发生了什么......

This is something many developers forget and is important because a small string may prevent the garbaging of a bigger char array. See this related question where I already pointed this : Java not garbage collecting memory. Many developers consider than the decision of Java designers to use this old optimization trick that was familiar to C coders did, in fact, more harm than good. Many of us know it because we were bitten by it and did have to look into Sun's source code to understand what happened...

正如Marko指出的那样(见下面的评论) ),在OpenJDK中,从java 7 Update 6开始, substring 不再共享char数组, String(String)构造函数是无用的。但它仍然很快(实际上甚至更快)并且由于此更改尚未传播到所有VM(可能不是所有客户),我建议保持这种最佳实践以使用 new String (substring)当旧行为证明它是正确的时候。

As Marko points out (see comments below), in OpenJDK, starting from java 7 Update 6, substring doesn't share the char array anymore and the String(String) constructor is, thus, useless. But it's still fast (even faster in fact) and as this change hadn't been propagated to all VM (and probably not all your customers) I'd recommend to keep this best-practice to use new String(substring) when the old behavior was justifying it.

这篇关于为什么String类有复制构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆