当前位置: 首页 > 面试题库 >

为什么String类具有复制构造函数?

王楚青
2023-03-14
问题内容

如果不可变的类对象副本将与原始副本相等,那么为什么StringJava 中的类具有副本构造函数?这是一个错误还是背后有原因?在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) {
 ....
 ....}

问题答案:

复制字符串的主要原因是为了 “修剪行李” ,即仅将底层char数组修剪为必需的字符。

基本的char数组可能太大,因为通过调用创建字符串时substring,char数组可以在新的字符串实例和源字符串实例之间共享;偏移量指向第一个字符,并且包括长度。

我使用的表达式 “修剪行李” 取自String复制构造函数的源代码:

  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;

这是许多开发人员忘记的事情,并且很重要,因为较小的字符串可能会阻止对较大的char数组进行破坏。看到这个相关的问题,实际上,许多开发人员认为Java设计师决定使用C编码人员熟悉的旧优化技巧,实际上弊大于利。我们中的很多人都知道它,因为我们被它咬了,不得不去研究Sun的源代码以了解发生了什么…

正如Marko指出的(请参阅下面的注释),从Java 7 Update
6开始,在OpenJDK中,substring不再共享char数组String(String),因此构造函数是无用的。但是它仍然很快(实际上甚至更快),并且由于此更改尚未传播到所有VM(可能不是所有客户),因此我建议new String(substring)在旧行为证明其正确性时保留使用最佳做法。



 类似资料:
  • 问题内容: Java为什么不支持C ++中的复制构造函数? 问题答案: Java。只是没有像在C ++中那样隐式地调用它们,我怀疑这是您的真正问题。 首先,复制构造函数无非是: 现在,C ++将使用以下语句隐式调用复制构造函数: 在这种情况下,克隆/复制在Java中根本没有意义,因为所有b1和b2都是引用,而不是像C 中那样的值对象。在C 中,该语句复制对象的状态。在Java中,它只是复制 引用

  • 可能重复:< br >什么是复制省略和返回值优化? 我很难理解为什么在下面的代码中没有调用复制构造函数。 有人能解释一下为什么只调用构造函数,不调用复制构造函数吗?< br >谢谢。

  • 问题内容: 为什么Java 中的类有一个? 我们无法实例化一个类,它的构造是什么? 有什么想法吗? 问题答案: Java中的构造函数实际上并不“构建”对象,而是用于初始化字段。 想象一下,您的抽象类具有字段x和y,并且无论最终创建什么实际的具体子类,您总是希望以某种方式对其进行初始化。因此,您将创建一个构造函数并初始化这些字段。 现在,如果您的抽象类有两个不同的子类,则在实例化它们时,将调用它们的

  • 可能重复:< br >什么是复制省略和返回值优化? 我有以下程序: 我期望的输出如下: 但我得到以下信息: 问题是:为什么不将对象从func返回到main调用我的复制构造函数?

  • 本文向大家介绍请解释Java中的概念,什么是构造函数?什么是构造函数重载?什么是复制构造函数?相关面试题,主要包含被问及请解释Java中的概念,什么是构造函数?什么是构造函数重载?什么是复制构造函数?时的应答技巧和注意事项,需要的朋友参考一下 考察点:JAVA构造函数 当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一

  • 有人能告诉我为什么我们需要将道具传递给构造函数()和super()。我读了很多关于这方面的问题,也读了很多文章。所有人都说你应该把道具传给构造函数和super,这样你就可以访问这个道具了。。。。。 如果我不将道具传递给构造函数或super,我的所有代码仍然可以工作。我看不出这会有什么变化。除非我想控制台记录this.props,这可以通过控制台记录来实现。 另一方面,我与一半的开发人员交谈过,他们