为什么 StringBuffer#append 抛出 StringIndexOutOfBoundsException
Why StringBuffer#append throws StringIndexOutOfBoundsException
我有尝试附加 2 个 SttringBuffers 的代码:
logBuf.append(errStrBuf);
在日志中我看到以下跟踪:
java.lang.StringIndexOutOfBoundsException: String index out of range: 90
at java.lang.AbstractStringBuilder.getChars(AbstractStringBuilder.java:325)
at java.lang.StringBuffer.getChars(StringBuffer.java:201)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:404)
at java.lang.StringBuffer.append(StringBuffer.java:253)
我无法理解问题的原因。
你能提供常量的例子吗?
会不会和并发有关?
你能提出解决方案吗?
是的,它可能与并发有关。根据 doc:
This method synchronizes on this (the destination) object but does not
synchronize on the source (sb).
因此,如果在此过程中更改errStrBuf
,则可能会产生此错误。自己同步,这样:
synchronize (errStrBuf) {
logBuf.append(errStrBuf);
}
无论 errStrBuf
发生什么变化,都使用相同的同步块。
一些关于 Java 来源的搜索显示 StringBuffer.append(StringBuffer sb)
代表 AbstractStringBuilder.append(StringBuffer sb)
这样做:
// Length of additional sb.
int len = sb.length();
// Make sure there's room.
ensureCapacityInternal(count + len);
// Copy them through.
sb.getChars(0, len, value, count);
StringBuffer.getChars
再次委托给 AbstractStringBuilder
所以 getChars
看起来有点像:
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
if (srcBegin < 0)
throw new StringIndexOutOfBoundsException(srcBegin);
if ((srcEnd < 0) || (srcEnd > count))
throw new StringIndexOutOfBoundsException(srcEnd);
if (srcBegin > srcEnd)
throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
请注意,您得到的是 String index out of range: 90 所以一定是 srcEnd > count
返回 true。因此,附加的字符串现在比传递的 len
短。很明显肯定是被别的线程乱动了。
我有尝试附加 2 个 SttringBuffers 的代码:
logBuf.append(errStrBuf);
在日志中我看到以下跟踪:
java.lang.StringIndexOutOfBoundsException: String index out of range: 90
at java.lang.AbstractStringBuilder.getChars(AbstractStringBuilder.java:325)
at java.lang.StringBuffer.getChars(StringBuffer.java:201)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:404)
at java.lang.StringBuffer.append(StringBuffer.java:253)
我无法理解问题的原因。
你能提供常量的例子吗?
会不会和并发有关?
你能提出解决方案吗?
是的,它可能与并发有关。根据 doc:
This method synchronizes on this (the destination) object but does not synchronize on the source (sb).
因此,如果在此过程中更改errStrBuf
,则可能会产生此错误。自己同步,这样:
synchronize (errStrBuf) {
logBuf.append(errStrBuf);
}
无论 errStrBuf
发生什么变化,都使用相同的同步块。
一些关于 Java 来源的搜索显示 StringBuffer.append(StringBuffer sb)
代表 AbstractStringBuilder.append(StringBuffer sb)
这样做:
// Length of additional sb.
int len = sb.length();
// Make sure there's room.
ensureCapacityInternal(count + len);
// Copy them through.
sb.getChars(0, len, value, count);
StringBuffer.getChars
再次委托给 AbstractStringBuilder
所以 getChars
看起来有点像:
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
if (srcBegin < 0)
throw new StringIndexOutOfBoundsException(srcBegin);
if ((srcEnd < 0) || (srcEnd > count))
throw new StringIndexOutOfBoundsException(srcEnd);
if (srcBegin > srcEnd)
throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
请注意,您得到的是 String index out of range: 90 所以一定是 srcEnd > count
返回 true。因此,附加的字符串现在比传递的 len
短。很明显肯定是被别的线程乱动了。