Joker
Joker

Reputation: 11150

ArrayIndexOutOfBoundException vs IndexOutOfBoundException

If we create a dummy ArrayList like below and call get method with -1 and 1 as argument. Then we get the following output:

Please explain the why there is difference between these two ?

Upvotes: 2

Views: 216

Answers (1)

Eran
Eran

Reputation: 394056

This is an implementation detail of ArrayList.

ArrayList is backed by an array. An access to an array with a negative index throws ArrayIndexOutOfBoundsException, so it doesn't have to be tested explicitly by the code of ArrayList class.

On the other hand, if you access the ArrayList with a non-negative index that is outside the range of the ArrayList (i.e. >= the size of the ArrayList), a specific check is performed in the following method, which throws IndexOutOfBoundsException:

/**
 * Checks if the given index is in range.  If not, throws an appropriate
 * runtime exception.  This method does *not* check if the index is
 * negative: It is always used immediately prior to an array access,
 * which throws an ArrayIndexOutOfBoundsException if index is negative.
 */
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

This check is necessary since the supplied index may be a valid index of the backing array (if it is smaller than the current capacity of the ArrayList), so accessing the backing array with an index >= the ArrayList's size will not necessarily throw an exception.

ArrayIndexOutOfBoundsException is a sub-class of IndexOutOfBoundsException, which means it is correct to say ArrayList's get method throws IndexOutOfBoundsException for both negative indices and indices >= the size of the list.

Note that unlike ArrayList, LinkedList throws IndexOutOfBoundsException for both negative and non-negative indices, since it is not backed by an array, so it cannot rely on an array to throw an exception for negative indices:

private void checkElementIndex(int index) {
    if (!isElementIndex(index))
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

/**
 * Tells if the argument is the index of an existing element.
 */
private boolean isElementIndex(int index) {
    return index >= 0 && index < size;
}

Upvotes: 6

Related Questions