Monday, May 19, 2014

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 - Solving Array IndexOutOfBoundsException in Java

If you are coming from C background than there is 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. Array is one of the most used data structure across all programming language and it’s no different in Java. In fact Java API has used array to build several useful data structures e.g. HashMap and ArrayList. These classes also throws IndexOutOfBoundsException if 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 biggest problem for new-comers, but, easiest to solve, once you know the basics. As name suggests, ArrayIndexOutOfBoundsException comes, when you try to access an invalid bound i.e. index. Array is 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 type of array, and it's index is zero based, which means first item exits in index 0, second at index 1, and last element at index 4 [length-1], this is where most mistakes are made. For getting a refresher in 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 sport 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 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 setup a breakpoint at the line, where you initialize the array and then just look at 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 advanced for-each loop from Java 5, which doesn't require an index, instead it automatically calculates index during iteration over 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 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 safe programming language and that's why you get this error when you try to access an out of bound index, this way Java prevents many malicious attacks, which is possible in C programming language.

4) Always remember, size of array is same as length of array and index starts from zero. So an array of size 5 or length 5 can contain five elements, but valid indexes are 0 to 4. 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, main thread died and so is our Java program. It's 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.

2 comments :

Anonymous said...

Excellent.. :)

Chris FAKAR said...

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.

Post a Comment