8

I will dive quick to the problem. I have a straightforward class

class Vector{
    float x, y;
}

and another class has an array of these objects as its member

Vector[] buffer;

I initialize it like this:

buffer = new Vector[8];
for(Vector v: buffer)
    v = new Vector();

but when I try to access this objects' members in this array I get a NullPointerException straight to my stack trace. That is, objects of array have not been constructed. On the other hand this more traditional code works just perfect:

buffer = new Vector[8];
for(int i = 0; i<8; i++)
    buffer[i] = new Vector;

As this discussion points it out, both should be the same after compilation.

My question is, why for each loop fails to initialize/construct objects from the item array?

Community
  • 1
  • 1
mehmetminanc
  • 1,359
  • 9
  • 14
  • If you use buffer.length in your for loop instead of repeating 8 then it will always be correct to the size of your array. Otherwise if you change one 8 and not the other then you will miss the end elements or get an array out of bound exception. – n00begon Sep 04 '12 at 01:43
  • It was just for the sake of example. Actually assigning buffer.length to a variable before for loop and using it for condition is a bit better for performance -almost negligible- and is my convention. – mehmetminanc Sep 04 '12 at 01:53
  • Well there is even a question about exactly that optimization http://stackoverflow.com/questions/1208320/what-is-the-cost-of-calling-array-length – n00begon Sep 04 '12 at 04:17

3 Answers3

5

In your for-each example you are overwriting the local variable of the loop which does not get saved back into the array. It is similar to in your second loop going:

for(int i = 0; i < buffer.length; i++){
    Vector v = buffer[i];
    v = new Vector();
}

Check out Understanding for each loop in Java for basically the same issue.

Community
  • 1
  • 1
n00begon
  • 3,503
  • 3
  • 29
  • 42
5

Both loops are the same for accessing elements from an array, but not for initializing them. When you use a for-each loop in this scenario, it's like doing

for(int x = 0; x < array.length; x++) {
    Vector v = array[x];
    v = new Vector();
}

You are not assigning the new Vector to the array, instead you are assigning it to a local variable.

Jeffrey
  • 44,417
  • 8
  • 90
  • 141
2

In your first example, v is available only inside the for loop. When you do v = new Vector(); v is updated, but not buffer[i]. v was pointing to buffer[i] before, now it points to a new vector, buffer[i] remains as null.

fastcodejava
  • 39,895
  • 28
  • 133
  • 186