Home What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
Reply: 15

What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?

Aaron
1#
Aaron Published in 2011-04-05 15:54:03Z

What does ArrayIndexOutOfBoundsException mean and how do I get rid of it?

Here is a code sample that triggers the exception:

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
  System.out.print(name[i] +'\n');
}
Makoto
2#
Makoto Reply to 2015-10-16 21:38:26Z

Your first port of call should be the documentation which explains it reasonably clearly:

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.

So for example:

int[] array = new int[5];
int boom = array[10]; // Throws the exception

As for how to avoid it... um, don't do that. Be careful with your array indexes.

One problem people sometimes run into is thinking that arrays are 1-indexed, e.g.

int[] array = new int[5];
// ... populate the array here ...
for (int index = 1; index <= array.length; index++)
{
    System.out.println(array[index]);
}

That will miss out the first element (index 0) and throw an exception when index is 5. The valid indexes here are 0-4 inclusive. The correct, idiomatic for statement here would be:

for (int index = 0; index < array.length; index++)

(That's assuming you need the index, of course. If you can use the enhanced for loop instead, do so.)

BalusC
3#
BalusC Reply to 2011-04-05 16:12:08Z
if (index < 0 || index >= array.length) {
    // Don't use this index. This is out of bounds (borders, limits, whatever).
} else {
    // Yes, you can safely use this index. The index is present in the array.
    Object element = array[index];
}

See also:

  • The Java Tutorials - Language Basics - Arrays

Update: as per your code snippet,

for(int i = 0; i<=name.length; i++) {

The index is inclusive the array's length. This is out of bounds. You need to replace <= by <.

for(int i = 0; i < name.length; i++) {
Teepeemm
4#
Teepeemm Reply to 2015-10-29 03:05:33Z

To put it briefly:

In the last iteration of

for(int i = 0; i<=name.length; i++) {

i will equal name.length which is an illegal index, since array indices are zero-based.

Your code should read

for(int i = 0; i < name.length; i++) 
                 ^
Octavian Damiean
5#
Octavian Damiean Reply to 2011-04-05 16:01:31Z

It means that you are trying to access an index of an array which is not valid as it is not in between the bounds.

For example this would initialize a primitive integer array with the upper bound 4.

int intArray[] = new int[5];

Programmers count from zero. So this for example would throw an ArrayIndexOutOfBoundsException as the upper bound is 4 and not 5.

intArray[5];
Lundin
6#
Lundin Reply to 2015-10-19 11:00:18Z

To avoid an array index out-of-bounds exception, one should use the enhanced-for statement where and when they can.

The primary motivation (and use case) is when you are iterating and you do not require any complicated iteration steps. You would not be able to use an enhanced-for to move backwards in an array or only iterate on every other element.

You're guaranteed not to run out of elements to iterate over when doing this, and your [corrected] example is easily converted over.

The code below:

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i< name.length; i++) {
    System.out.print(name[i] + "\n");
}

...is equivalent to this:

String[] name = {"tom", "dick", "harry"};
for(String firstName : name) {
    System.out.println(firstName + "\n");
}
Tobb
7#
Tobb Reply to 2017-02-03 13:20:53Z

What causes ArrayIndexOutOfBoundsException?

If you think of a variable as a "box" where you can place a value, then an array is a series of boxes placed next to eachother, where the number of boxes is a finite and explicit integer.

Creating an array like this:

final int[] myArray = new int[5]

creates a row of 5 boxes, each holding an int. Each of the boxes have an index, a position in the series of boxes. This index starts at 0, and ends at N-1, where N is the size of the array (the number of boxes).

To retrieve one of the values from this series of boxes, you can refer to it through its index, like this:

myArray[3]

Which will give you the value of the 4th box in the series (since the first box has index 0).

An ArrayIndexOutOfBoundsException is caused by trying to retrive a "box" that does not exist, by passing an index that is higher than the index of last "box", or negative.

With my running example, these code snippets would produce such an exception:

myArray[5] //tries to retrieve the 6th "box" when there is only 5
myArray[-1] //just makes no sense
myArray[1337] //waay to high

How to avoid ArrayIndexOutOfBoundsException

In order to prevent ArrayIndexOutOfBoundsException, there are some key points to consider:

Looping

When looping through an array, always make sure that the index you are retrieving is strictly smaller than the length of the array (the number of boxes). For instance:

for (int i = 0; i < myArray.length; i++) {

Notice the <, never mix a = in there..

You might want to be tempted to do something like this:

for (int i = 1; i <= myArray.length; i++) {
    final int someint = myArray[i - 1]

Just don't. Stick to the one above (if you need to use the index) and it will save you a lot of pain.

Where possible, use foreach:

for (int value : myArray) {

This way you won't have to think about indexes at all.

When looping, whatever you do, NEVER change the value of the loop iterator (here: i). The only place this should change value is to keep the loop going. Changing it otherwise is just risking an exception, and is in most cases not neccessary.

Retrieval/update

When retrieving an arbitrary element of the array, always check that it is a valid index against the length of the array:

public Integer getArrayElement(final int index) {
    if (index < 0 || index >= myArray.length) {
        return null; //although I would much prefer an actual exception being thrown when this happens.
    }
    return myArray[index];
}
Peter Mortensen
8#
Peter Mortensen Reply to 2017-12-17 10:03:21Z

In your code you have accessed the elements from index 0 to the length of the string array. name.length gives the number of string objects in your array of string objects i.e. 3, but you can access only up to index 2 name[2], because the array can be accessed from index 0 to name.length - 1 where you get name.length number of objects.

Even while using a for loop you have started with index zero and you should end with name.length - 1. In an array a[n] you can access form a[0] to a[n-1].

For example:

String[] a={"str1", "str2", str3" ..., "strn"};

for(int i=0;i<a.length()i++)
    System.out.println(a[i]);

In your case:

String[] name = {"tom", "dick", "harry"};

for(int i = 0; i<=name.length; i++) {
    System.out.print(name[i] +'\n');
}
Satyendra Kumar
9#
Satyendra Kumar Reply to 2017-10-25 07:38:27Z

So much for this simple question, but I just wanted to highlight a new feature in Java which will avoid all confusions around indexing in arrays even for beginners. Java-8 has abstracted the task of iterating for you.

int[] array = new int[5];

//If you need just the items
Arrays.stream(array).forEach(item -> { println(item); });

//If you need the index as well
IntStream.range(0, array.length).forEach(index -> { println(array[index]); })

What's the benefit? Well, one thing is the readability like English. Second, you need not worry about the ArrayIndexOutOfBoundsException

adn.911
10#
adn.911 Reply to 2017-11-30 16:41:17Z

ArrayIndexOutOfBoundsException means that you are trying to access an index of the array that does not exist or out of the bound of this array. Array indexes start from 0 and end at length - 1.

In your case

for(int i = 0; i<=name.length; i++) {
    System.out.print(name[i] +'\n'); // i goes from 0 to length, Not correct
}

ArrayIndexOutOfBoundsException happens when you are trying to access the name.length indexed element which does not exist (array index ends at length -1). just replacing <= with < would solve this problem.

for(int i = 0; i < name.length; i++) {
    System.out.print(name[i] +'\n');  // i goes from 0 to length - 1, Correct
}
Peter Mortensen
11#
Peter Mortensen Reply to 2017-12-17 09:54:34Z

The most common case I've seen for seemingly mysterious ArrayIndexOutOfBoundsExceptions, i.e. apparently not caused by your own array handling code, is the concurrent use of SimpleDateFormat. Particularly in a servlet or controller:

public class MyController {
  SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");

  public void handleRequest(ServletRequest req, ServletResponse res) {
    Date date = dateFormat.parse(req.getParameter("date"));
  }
}

If two threads enter the SimplateDateFormat.parse() method together you will likely see an ArrayIndexOutOfBoundsException. Note the synchronization section of the class javadoc for SimpleDateFormat.

Make sure there is no place in your code that are accessing thread unsafe classes like SimpleDateFormat in a concurrent manner like in a servlet or controller. Check all instance variables of your servlets and controllers for likely suspects.

Peter Mortensen
12#
Peter Mortensen Reply to 2017-12-17 10:00:09Z

You are getting ArrayIndexOutOfBoundsException due to i<=name.length part. name.length return the length of the string name, which is 3. Hence when you try to access name[3], it's illegal and throws an exception.

Resolved code:

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i < name.length; i++) { //use < insteadof <=
  System.out.print(name[i] +'\n');
}

It's defined in the Java language specification:

The public final field length, which contains the number of components of the array. length may be positive or zero.

Peter Mortensen
13#
Peter Mortensen Reply to 2017-12-17 10:02:04Z

That's how this type of exception looks when thrown in Eclipse. The number in red signifies the index you tried to access. So the code would look like this:

myArray[5]

The error is thrown when you try to access an index which doesn't exist in that array. If an array has a length of 3,

int[] intArray = new int[3];

then the only valid indexes are:

intArray[0]
intArray[1]
intArray[2]

If an array has a length of 1,

int[] intArray = new int[1];

then the only valid index is:

intArray[0]

Any integer equal to the length of the array, or bigger than it: is out of bounds.

Any integer less than 0: is out of bounds;

P.S.: If you look to have a better understanding of arrays and do some practical exercises, there's a video here: tutorial on arrays in Java

nIKHIL
14#
nIKHIL Reply to 2018-01-16 12:13:33Z

For your given array the length of the array is 3(i.e. name.length = 3). But as it stores element starting from index 0, it has max index 2.

So, instead of 'i**<=name.length' you should write 'i<**name.length' to avoid 'ArrayIndexOutOfBoundsException'.

Peter Mortensen
15#
Peter Mortensen Reply to 2017-12-17 09:58:06Z

For any array of length n, elements of the array will have an index from 0 to n-1.

If your program is trying to access any element (or memory) having array index greater than n-1, then Java will throw ArrayIndexOutOfBoundsException

So here are two solutions that we can use in a program

  1. Maintaining count:

    for(int count = 0; count < array.length; count++) {
        System.out.println(array[count]);
    }
    

    Or some other looping statement like

    int count = 0;
    while(count < array.length) {
        System.out.println(array[count]);
        count++;
    }
    
  2. A better way go with a for each loop, in this method a programmer has no need to bother about the number of elements in the array.

    for(String str : array) {
        System.out.println(str);
    }
    
Peter Mortensen
16#
Peter Mortensen Reply to 2017-12-17 09:55:16Z

You could not iterate or store more data than the length of your array. In this case you could do like this:

for (int i = 0; i <= name.length - 1; i++) {
    // ....
}

Or this:

for (int i = 0; i < name.length; i++) {
    // ...
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.405151 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO