请向我解释一下Java中String构造函数的代码片段?

时间:2013-03-30 09:09:18

标签: java string

以下是Java中String对象的构造函数之一:

public String(String original) {
    int size = original.count;
    char[] originalValue = original.value;
    char[] v;
    if (originalValue.length > size) {
        // The array representing the String is bigger than the new
        // String itself.  Perhaps this constructor is being called
        // in order to trim the baggage, so make a copy of the array.
        int off = original.offset;
        v = Arrays.copyOfRange(originalValue, off, off+size);
    } else {
        // The array representing the String is the same
        // size as the String, so no point in making a copy.
        v = originalValue;
    }
    this.offset = 0;
    this.count = size;
    this.value = v;
}

代码行 if(originalValue.length> size)是我关心的,我不认为这个条件对于正在执行的IF内的所有代码都是正确的。 String实际上是一个字符数组。 original.count 应该等于其值的长度(其值是一个字符数组),因此不会发生这种情况。

我可能错了,所以我需要你的解释。谢谢你的帮助。

VipHaLong。

2 个答案:

答案 0 :(得分:9)

  

String实际上是一个字符数组

不,不是。它是一个对象,内部有一个引用到一个字符数组。

  

original.count应该等于它的值的长度(它的值是一个字符数组)

不一定。这取决于您正在查看的Java的确切版本,但直到最近,几个字符串可以引用相同的char[],每个字符串使用数组的不同部分。

例如,如果你有:

String longString = "this is a long string";
String shortString = longString.substring(0, 2);

...引用shortString的对象将使用原始字符串引用的相同char[],但起始偏移量为0且计数为2.因此,如果您随后调用:

String copyOfShortString = new String(shortString);

确实会进入您在问题中关注的if区块。

从Java 7更新5开始,Oracle JRE已更改为使substring始终复制。 (这背后的利弊可能会变得非常复杂,但值得了解这两个系统。)

看起来您正在查看的代码版本是旧版本,其中字符串对象可以共享基础数组但查看不同部分。

答案 1 :(得分:3)

您正在查看的String实现在创建子字符串时不会复制字符数据。相反,多个String对象可以引用相同的字符数组,但具有不同的offsetcount(因此length)。

因此,if条件实际上可以成立。

请注意,在最新版本的Oracle JDK中已删除此字符数组共享。