Blankj/AndroidUtilCode · error · IndexOutOfBoundsException

Index: {}, Length: {}

Error message

Index: {}, Length: {}

What it means

Thrown by ArrayUtils.realAdd when inserting a single element at an index outside the closed range [0, array.length] for a non-null array. The guard rejects index > length and index < 0 before allocating the length+1 result array, protecting the subsequent System.arraycopy.

Source

Thrown at lib/utilcode/src/main/java/com/blankj/utilcode/util/ArrayUtils.java:881

    @NonNull
    public static double[] add(@Nullable double[] array, int index, double element) {
        return (double[]) realAdd(array, index, element, Double.TYPE);
    }

    @NonNull
    private static Object realAdd(@Nullable Object array, int index, @Nullable Object element, Class clss) {
        if (array == null) {
            if (index != 0) {
                throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
            }
            Object joinedArray = Array.newInstance(clss, 1);
            Array.set(joinedArray, 0, element);
            return joinedArray;
        }
        int length = Array.getLength(array);
        if (index > length || index < 0) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
        }
        Object result = Array.newInstance(clss, length + 1);
        System.arraycopy(array, 0, result, 0, index);
        Array.set(result, index, element);
        if (index < length) {
            System.arraycopy(array, index, result, index + 1, length - index);
        }
        return result;
    }

    ///////////////////////////////////////////////////////////////////////////
    // remove
    ///////////////////////////////////////////////////////////////////////////

    /**
     * <p>Removes the element at the specified position from the specified array.
     * All subsequent elements are shifted to the left (substracts one from
     * their indices).</p>

View on GitHub (pinned to 7b4caf9e54)

Solutions

  1. To append, pass index = array.length exactly (not length+1).
  2. Validate 0 <= index && index <= array.length before calling add.
  3. Use ArrayUtils.add(array, element) overload (no index) when you only need append semantics if available, or compute index defensively.
  4. When the index comes from external input, clamp to the valid range.

Example fix

// before
int[] a = {1, 2, 3};
int[] r = ArrayUtils.add(a, 5, 9); // Index: 5, Length: 3

// after
int[] r = ArrayUtils.add(a, a.length, 9); // append at end
Defensive patterns

Strategy: validation

Validate before calling

int len = (array == null) ? 0 : array.length;
int safeIndex = (index < 0) ? 0 : Math.min(index, len);
int[] r = ArrayUtils.add(array, safeIndex, element);

Try / catch

try {
    r = ArrayUtils.add(array, index, element);
} catch (IndexOutOfBoundsException e) {
    r = ArrayUtils.add(array, array.length, element); // safe append
}

Prevention

When it happens

Trigger: Calling add(array, index, element) on a non-null array with a negative index or an index greater than array.length (e.g., length+1 to 'append' — illegal; append requires exactly array.length).

Common situations: Appending with index = array.length + 1 instead of array.length; passing a 1-based index; off-by-one loop counters; using size() of a different collection as the index.

Related errors


AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14). Data as JSON: /api/errors/6fd2de5237081f89. Report an issue: GitHub.