didi/DoKit · error · IndexOutOfBoundsException

Index: " + index + ", Length: " + length

Error message

Index: " + index + ", Length: " + length

What it means

The non-null branch of realAdd validates the insertion index for a single element: it must satisfy 0 <= index <= length. Anything larger or negative would create an uninitialized gap in the new array, so it throws IndexOutOfBoundsException with the offending index and the actual length.

Source

Thrown at Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/ArrayUtils.java:882

    @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 626827cddb)

Solutions

  1. Clamp the index before the call: index = Math.max(0, Math.min(index, array.length))
  2. Convert binarySearch results correctly: int insertAt = -(pos) - 1;
  3. For append, use ArrayUtils.add(array, element) (end insertion) instead of computing index manually

Example fix

// before
int pos = Arrays.binarySearch(arr, key);
int[] out = ArrayUtils.add(arr, pos, value); // pos is negative when absent

// after
int pos = Arrays.binarySearch(arr, key);
int insertAt = pos >= 0 ? pos : -(pos) - 1;
int[] out = ArrayUtils.add(arr, insertAt, value);
Defensive patterns

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: Calling ArrayUtils.add(array, index, element) with index > array.length or index < 0 — off-by-one appends (index = length + 1), negative results from binarySearch/indexOf used unchecked, or indices computed against a longer copy of the data.

Common situations: Using arrays.binarySearch's negative insertion points incorrectly (must be -(idx)-1). Cursor positions from UI (list scroll position) applied to a shorter backing array after a data refresh. Loop counters that overshoot by one.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/4186592f0fe4d95b. Report an issue: GitHub.