为什么字符串类有无参数构造函数和以字符串文字作为参数的构造函数?

问题描述 投票:0回答:1

采用字符串文字参数的 String 构造函数具有以下实现。

   @IntrinsicCandidate
    public String(String original) {
        this.value = original.value;
        this.coder = original.coder;
        this.hash = original.hash;
    }

据我了解,原始字符串文字(传递的参数)的值被分配给堆内存中新创建的对象。因此,我们有两个对象,一个在字符串文字池中,另一个在堆内存中。我假设由于字符串文字池不会被垃圾收集,因此创建的文字将保留在文字池中直到应用程序结束。这不是浪费内存资源吗?

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.

我相信源代码中的这条注释表明我们不要使用这个构造函数,除非需要显式副本,并且由于字符串是不可变的,所以这是不必要的。他们是否建议我们不要使用它,因为它很浪费,或者背后还有其他原因吗?如果他们确实建议不要使用它,因为它很浪费,为什么他们还要实现这个和无参数构造函数(那里的评论也说它是不必要的)?

难道他们不能只拥有采用字符数组、字节数组等的构造函数...而不是这两个构造函数吗?

Java 字符串创建和字符串池 上面的线程回答说,当您使用

new String("Argument")
时,确实会创建字符串文字,但我想知道的是为什么他们决定使用
String()
String("argument")
,如果它很浪费,而且他们自己建议不要这样做用吗?

java string implementation pool string-literals
1个回答
0
投票

这个构造函数的存在是有历史原因的。

在 Java 1.7 的早期版本和以前的版本中(也检查了 Java 1.5),

substring(int, int)
方法进行了优化,以便返回的字符串与原始字符串共享支持字符数组(调用内部构造函数的摘录):

public String substring(int beginIndex, int endIndex) {
    new String(offset + beginIndex, endIndex - beginIndex, value);
}

包私有构造函数:

String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

这样做的好处是以下操作不会复制字符:

String s1 = readSomeLongStringFromAFile("somefile.txt");
String s2 = s1.substring(2, s1.length()-2);

它的缺点是,在以下情况下,即使没有重用,支持字符数组也可能保留在内存中:

String getStartFromFile(String filename) {
    String s1 = readSomeLongStringFromAFile("somefile.txt");
    String s2 = s1.substring(0, 2);
    return s2;
}

在这种情况下,使用复制构造函数是有益的,因为复制构造函数仅从后备数组中复制所需的字符:

String getStartFromFile(String filename) {
    String s1 = readSomeLongStringFromAFile("somefile.txt");
    String s2 = s1.substring(0, 2);
    return new String(s2);
}

链接的源代码来自Java 1.7-b24,在最新版本的Java 1.7(1.7u351-ga)中,这个包私有构造函数已经消失了。

但是仍然有代码使用

String(String)
构造函数,并且 Java 试图尽可能避免破坏现有代码,这意味着
String(String)
复制构造函数在这里是为了迷惑人们。

© www.soinside.com 2019 - 2024. All rights reserved.