RFR 8135248: Add utility methods to check indexes and ranges

Paul Sandoz paul.sandoz at oracle.com
Mon Sep 21 15:21:04 UTC 2015


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



More information about the core-libs-dev mailing list