Java ArrayIndexOutOfBoundsException

In this article, we will take a detailed look at ArrayIndexOutOfBoundsException and will cover below topics
What is it?
When it occurs?
How to prevent it?
How to handle it?

Overview
Elements of a java array have a numeric index and they can be accessed using this index.
Index of first element is 0, second is 1 and so on. Last array element has an index equal to the total number of array elements – 1.
So, the range of indexes of an array is

from 0 till (length of array – 1)

If you try to access an array element outside this range, it throws java.lang.ArrayIndexOutOfBoundsException.
Thus, this exception is thrown to indicate that you have accessed an illegal array index.

Since the compiler cannot check if the index being accessed is valid or not, no error is flagged at compile time but, a runtime exception is thrown.

ArrayIndexOutOfBoundsException is an unchecked exception, meaning that the compiler cannot check that this exception might be thrown.

Since it is an unchecked exception:
1. It is not necessary for a method to declare that it will throw this exception in its signature even if it explicitly throws it.
2. It extends java.lang.RuntimeException class.

Java docs for ArrayIndexOutOfBoundsException state,

Thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.

Note that you will also get this exception when trying to access an illegal index of a collection that uses an array internally.
Causes
There may be many scenarios where ArrayIndexOutOfBoundsException can occur but the main reason behind all will be the same, Trying to access an invalid array index.
1. Direct access
Suppose you have an array of 3 elements. Its range of indexes will be 0, 1, 2.
If any other index either positive or negative is accessed, it will raise ArrayIndexOutOfBoundsException.
Example,

String[] names = {"A", "B", "C"};
String name = names[1]; // valid
name = names[2]; // valid

name = names[-1]; // exception
name = names[3]; // exception
name = names[5]; // exception

Statement which tries to access -1 index will raise below error

Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 3

2. Accessing array elements in a loop
When iterating over an array, this is the most common mistake done by developers that they provide the loop counter from 0 till the length of the array.
Upper limit of valid index is 1 lesser than the length of array. Example,

String[] names = { "A", "B", "C" };
for(int i = 0; i <= names.length; i++) {
  String name = names[i];
}

The last loop iteration will raise an error

Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3

Since index 3 is out of range for the array.
3. Accessing invalid index in Arrays.asList()
Arrays.asList() method returns a list of type Arrays$ArrayList, which means it is an object of an inner class named ArrayList of java.util.Arrays class.

It has all the methods defined in java.util.ArrayList since this class serves as a bridge between arrays and collections as per the documentation

This method acts as bridge between array-based and collection-based APIs

List returned by Arrays.asList() is backed by an array. If you try to access an invalid index using its get() method, then it will raise ArrayIndexOutOfBoundsException. Example,

List<String> l1 = Arrays.asList("A", "B");
l1.get(0); // works
l1.get(1); // works

l1.get(3); // exception
l1.get(-1); // exception

Prevention
Following are the pointers that should be considered when accessing array elements to prevent ArrayIndexOutOfBoundsException.
1. Be careful with indexes
Remember the upper bound of array, which is equal to length of array – 1. Always ensure to access array elements between below range

0 <= index < Array length – 1

2. Iterate using  enhanced for loop
Instead of using index based for loop, use enhanced for loop to iterate over an array.
Since, it does not uses index to access array elements, there is no chance of ArrayIndexOutOfBoundsException. Example,

String[] names = { "A", "B", "C" };
for(String name : names) {
  // code
}

3. Use an iterator
For iterating over a list returned by Arrays.asList() or any other collection that uses an array at the back, use an iterator as shown below.

List<String> l = Arrays.asList("A", "B");
Iterator<String> iterator = l.iterator();
while(iterator.hasNext()){
  String name = iterator.next();
}

hasNext() method of iterator will only return true when there is an element ahead, thus eliminating the possibility of ArrayIndexOutOfBoundsException
4. Use java 8 forEach()
To avoid ArrayIndexOutOfBoundsException raised while iterating a collection, java 8 provides a forEach() method.
This method can only be used on collections such as a List or Set and not on simple arrays. Example,

List<String> l = Arrays.asList("A", "B"); 
l.forEach(name -> {
  System.out.print(name);
});

Handle ArrayIndexOutOfBoundsException
It is a best practice to be cautious that this exception does not occur but even if it occurs, then it can be handled using java try-catch block as shown below

String[] names = { "A", "B", "C" };
try {
  for (int i = 0; i <= names.length; i++) {
    String name = names[i];
  }
} catch (ArrayIndexOutOfBoundsException e) {
  System.out.println("Error: " + e.getMessage());
}

Below is the output

Error: Index 3 out of bounds for length 3

which clearly tells what the problem is.

Hope the article on java ArrayIndexOutOfBoundsException was useful