Monday, August 2, 2021

How to Fix Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: in Java? Solution

If you are coming from C background than there is a pleasant surprise for you, Java programming language provides implicit bound checks on Array, which means an invalid array index access is not allowed in Java and it will result in java.lang.ArrayIndexOutOfBoundsException. An array is one of the most used data structures across all programming language and it’s no different in Java. In fact, Java API has used an array to build several useful data structures e.g. HashMap and ArrayList. These classes also throw IndexOutOfBoundsException if an invalid index is supplied to their get(int index) methods. One of the common mistakes Java programmer makes is invalid end condition on classical index-based for loops.

Since more often than not, you write code to loop over array or list in Java, a wrong end condition can result in Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException, as shown in next section.

Along with java.lang.NullPointerException, this exception is the biggest problem for new-comers, but, easiest to solve, once you know the basics.

As the name suggests, ArrayIndexOutOfBoundsException comes, when you try to access an invalid bound i.e. index. The array is a fixed-length data structure, once created and initialized, you cannot change its size.

If an array is created with size 5 means it has five slots to hold items depending upon the type of array, and its index is zero-based, which means the first item exits in index 0, second at index 1, and the last element at index 4 [length-1], this is where most mistakes are made. For getting a refresher in the array, please see Java Array 101.




Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5

Now let's diagnose this error message, which I guess every Java programmer has seen during his learning experience. "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException : 5" says that, our code has got java.lang.ArrayIndexOutOfBoundsException, while accessing an index 5, which also that means index  5 is illegal for this array.

If you look closely, It also tells us that this Exception has occurred in main thread and because it was uncaught, main thread has finished abruptly and so is our Java program. Now let's look at our code, which is causing this error :

public class UnderstandingArrayIndexOutOfBounds{

    public static void main(String args[]) {
        String[] currencies = {"GBP", "USD", "JPY", "EUR", "INR"};
        System.out.println("Supported currencies for trading : ");
        for (int i = 0; i <= currencies.length; i++) {
            System.out.println(currencies[i]);
        }
    }

}
Output :
Supported currencies for trading :
GBP
USD
JPY
EUR
INR
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
        at Testing.main(Testing.java:17)

Can you spot the mistake? Yes, it's subtle and not easy to find if you are new to Java. Condition in for loop is wrong, it should be i instead of i<=currencies.length, because array index starts at zero. 

Due to this error, our for loop runs one iteration more than expected and though our program correctly prints all supported currencies, it died due to uncaught java.lang.ArrayIndexOutOfBoundsException in the end. 

This error comes when the loop runs at 6th time, to access 6th element (index 5). That's why you should always pay attention, while looping over array in Java. You can also see your array's content at runtime by debugging your Java program in Eclipse

Just set up a breakpoint at the line, where you initialize the array, and then just look at the variables window in debug perspective of Eclipse IDE. You can see your array in tabular format as shown below :




Iterating Over Array using ForEach Loop

Alternatively, you can also use the advanced for-each loop from Java 5, which doesn't require an index, instead it automatically calculates index during iteration over the array, as shown below :

public class LoopingOverArrayUsingForEach{

    public static void main(String args[]) {
        String[] currencies = {"GBP", "USD", "JPY", "EUR", "INR"};
        System.out.println("Supported currencies for trading : ");
        for (String currency : currencies) {
            System.out.println(currency);
        }
    }

}
Output:
Supported currencies for trading :
GBP
USD
JPY
EUR
INR

Things to remember about ArrayIndexOutOfBoundsException in Java

One of the most important thing to solve any error is to know more about that error. Rather than being reactive, be proactive. As part of your learning process you should know in and out of IndexOfBoundsException and particularly ArrayIndexOutOfBoundsException. Here is some of the important details of this beginner's nemesis :

1) Like java.lang.NullPointerException, this is also an unchecked exception in Java. It's a sub-class of RuntimeException and doesn't need to be declared by throws clause, but it's better to document if your method can throw ArrayIndexOutBoundsException.

2) It's also sub-class of IndexOutOfBoundsException in Java, which means if you have a catch block for catching IndexOutOfBoundsException, you will implicitly catch java.lang.ArrayIndexOutOfBoundsException as shown below :

try{
     int[] numbers = {10, 100, 1000, 10000, 100000};
     int number = numbers[5];
     System.out.println(number);
} catch(IndexOutOfBoundsException ioob){
     ioob.printStackTrace();
}
Output:
java.lang.ArrayIndexOutOfBoundsException: 5

You can see, we haven't got "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5" , rather we just got "java.lang.ArrayIndexOutOfBoundsException: 5", because this time we have caught the exception, which means main thread is not died and finished normally.

3) Java is a safe programming language and that's why you get this error when you try to access an out of the bound index, this way Java prevents many malicious attacks, which is possible in C programming language.

4) Always remember, the size of the array is the same as the length of the array and the index starts from zero. So an array of size 5 or length 5 can contain five elements, but valid indexes are 0 to 4. A negative index is also invalid.


That's all about Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException, as I said this error message shows that we have an ArrayIndexOutOfBoundsException in main thread because it was uncaught, the main thread died and so is our Java program. It's a runtime exception so you don't need to declare it on throws clause and it's also sub-class of IndexOutOfBoundsException, which means it can be caught by IndexOutOfBoundsException catch block.

8 comments:

  1. In most cases I personally thing advanced for-loop is better if you don't know about length-1. Makes code clear and easy for read but skips understanding of arrays. Personally my opinion is people forget arrays are zero-indexed.

    ReplyDelete
  2. Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
    at LargestOf3.main(LargestOf3.java:11)
    can som1 help me with this?

    ReplyDelete
  3. @Elie, it looks like your class LargestOf3.java has error on 11th line, where you are accessing 4th element (3rd index) in an array of 3 element, which means only 0, 1 and 2 are valid.

    ReplyDelete
  4. Sometime we get ArrayIndexOutOfBoundsException even if you are using array e.g. while using List, Hashtable etc? do you know why?

    ReplyDelete
  5. @Anonymous, that's true, you can get ArrayIndexOutOfBoundsException even while using List and Hashtable because they internally use array. ArrayList is backed by array and Hashtable also uses an array table for holding buckets.

    ReplyDelete
  6. enter the string
    this my class
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
    at Reverse1.main(Reverse1.java:19)
    any one suggest me how to remove this error
    Press any key to continue . . .

    ReplyDelete
  7. Thanks very helpful I was facing same problem.....you helped me a lot.

    ReplyDelete