On 21 Sep 2015, at 16:17, Roger Riggs <roger.ri...@oracle.com> 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.

Reply via email to