Java String Builder附加计算

时间:2015-05-06 11:32:28

标签: java concatenation stringbuilder

当我使用StringBuilder的附加时,实际复制何时发生 - 当我调用append()或者我将构建器评估为字符串时?

我问,因为在我的应用程序中我有很多log.debug(strA + strB + ...)行,我想避免评估生产代码中的连接。我知道java优化+操作并将它们转换为字符串构建器附加但我不知道连接函数中是否真的发生了连接。

4 个答案:

答案 0 :(得分:3)

StringBuilder包含一系列字符。 append()为该数组添加了字符。一旦显式或隐式地调用stringBuilderInstance.toString(),就会根据stringbuilder的内容创建一个新的String实例。

答案 1 :(得分:3)

在追加StringBuilder时,表示您正在连接字符串。不,内部创建了额外的对象。它只是追加!当您使用StringBuilderString转换为.toString()时,内容副本将从StringBuilder转换为String个对象。

答案 2 :(得分:1)

两者。当您附加到StringBuilder时,您将字符复制到其内部字符数组中。将构建器转换为字符串时,将内容复制到String实例的内部数组中。

答案 3 :(得分:0)

StringBuilder扩展了AbstractStringBuilder,里面有几个append方法:

public AbstractStringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}


public AbstractStringBuilder append(StringBuffer sb) {
    if (sb == null)
        return appendNull();
    int len = sb.length();
    ensureCapacityInternal(count + len);
    sb.getChars(0, len, value, count);
    count += len;
    return this;
}

AbstractStringBuilder append(AbstractStringBuilder asb) {
    if (asb == null)
        return appendNull();
    int len = asb.length();
    ensureCapacityInternal(count + len);
    asb.getChars(0, len, value, count);
    count += len;
    return this;
}

@Override
public AbstractStringBuilder append(CharSequence s) {
    if (s == null)
        return appendNull();
    if (s instanceof String)
        return this.append((String)s);
    if (s instanceof AbstractStringBuilder)
        return this.append((AbstractStringBuilder)s);

    return this.append(s, 0, s.length());
}

它使用char[] value;声明来声明所有字符的存储空间。 当您追加新字符串时,它会检查value数组的当前长度,如果有必要,则调用ensureCapacityInternal

private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0)
        expandCapacity(minimumCapacity);
}

并在必要时调用expandCapacity

/**
 * This implements the expansion semantics of ensureCapacity with no
 * size check or synchronization.
 */
void expandCapacity(int minimumCapacity) {
    int newCapacity = value.length * 2 + 2;
    if (newCapacity - minimumCapacity < 0)
        newCapacity = minimumCapacity;
    if (newCapacity < 0) {
        if (minimumCapacity < 0) // overflow
            throw new OutOfMemoryError();
        newCapacity = Integer.MAX_VALUE;
    }
    value = Arrays.copyOf(value, newCapacity);
}

结论:当您追加新数据时,复制正在调用,并且字符values数组的容量不足以存储此新数据。