On 21 Sep 2015, at 16:17, Roger Riggs <[email protected]> wrote:
> Hi Paul,
>
> java.util.Arrays.java: line 5236: new IndexOutOfBoundsException()
> - It is always appreciated when debugging to be given a message with the
> index that is out of range and the range expected.
>
Added:
? new IndexOutOfBoundsException(String.format(
"Out of bounds for range [0, %d) with out of bound values %d and %d", length,
a, b))
> When converting existing code, is it expected that the exception messages
> will be unchanged?
>
Yes, that is intention, based on looking at various use-cases in
Arrays/Spliterators/String/AbstractString/AbstractStringBuilder/*Buffer. I
could have missed a few cases. Note that one can always play the “capture” card
at the expense of an allocation per check. which may be less of a concern for
the sub-range checks.
> I can't quite visualize how this would be applied to existing code.
Existing code would provide an instance of OutOfBoundsToException for each
particular use-case.
Take this following method in String:
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
Which could be updated as follows (modulo using lambdas early in at start up):
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
Arrays.checkFromToIndex(srcBegin, srcEnd, value.length, (f, t, l) -> {
long v;
if (f < 0) {
v = f;
} else if (t > l) {
v = t;
} else v = t - f;
return new StringIndexOutOfBoundsException((int) v);
});
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
Or the following in AbstractStringBuilder:
public AbstractStringBuilder insert(int index, char[] str, int offset,
int len)
{
if ((index < 0) || (index > length()))
throw new StringIndexOutOfBoundsException(index);
if ((offset < 0) || (len < 0) || (offset > str.length - len))
throw new StringIndexOutOfBoundsException(
"offset " + offset + ", len " + len + ", str.length "
+ str.length);
ensureCapacityInternal(count + len);
System.arraycopy(value, index, value, index + len, count - index);
System.arraycopy(str, offset, value, index, len);
count += len;
return this;
}
public AbstractStringBuilder insert(int index, char[] str, int offset,
int len)
{
Arrays.checkIndex(index, length(),
(i, a, l) -> new StringIndexOutOfBoundsException((int)
i));
Arrays.checkFromIndexSize(offset, len, str.length,
(f, s, l) -> new StringIndexOutOfBoundsException(
"offset " + f + ", len " + s + ", str.length " +
l));
ensureCapacityInternal(count + len);
System.arraycopy(value, index, value, index + len, count - index);
System.arraycopy(str, offset, value, index, len);
count += len;
return this;
}
The casts obviously suck, but that could be solved with a new (package private,
maybe) constructor. One thing we could do to improve the situation is add
factory methods to IOOBE, AIOOBE, SIOOBE for the three use-cases such that
method refs could be easily be used.
> Will there be any benefit to adding static checking methods to the typically
> thrown exceptions
> that can be used as method references instead of the implicitly defined
> lambdas?
>
> typo:
>
> test/java/util/Arrays/CheckIndex.java:
> - line 78, 91, etc "withing" -> “within”
>
Thanks, updated,
Paul.