2

这是 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应该等于它的值的长度(它的值是一个字符数组),所以这种情况不会发生。

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

维哈隆。

4

2 回答 2

9

字符串实际上是一个字符数组

不,这不对。它是一个在内部具有对字符数组的引用的对象。

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始终获取副本。(这背后的利弊可能会变得相当复杂,但值得了解这两个系统。)

It looks like the version of code you're looking at is an older version where string objects could share an underlying array but view different portions.

于 2013-03-30T09:12:49.737 回答
3

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

因此,该if条件实际上可以为真。

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

于 2013-03-30T09:12:45.247 回答