user2899587
user2899587

Reputation: 189

Specific NullPointerException Java

i have short question, tell me just why first example don't work and second works. Code before examples:

Tiles[] myTiles = new Tile[23];
number = 1;

First Example:

for(Tile tile : this.myTiles) {
    if (number != this.myTiles.length) {
        tile = new Tile(number, getResources().getColor(R.color.puzzle_default));
        number++;
    }
}

Second Example:

for(Tile tile : this.myTiles) {
    if (number != this.myTiles.length){
        this.myTiles[number-1] = new Tile(number, getResources().getColor(R.color.puzzle_default));
        number++;
    }
}

If i use code below in other method in class

this.myTiles[0].getNumber(); 

It's NullPointerException.
But with Second Example it nicely works.

I really don't know why. Thanks for any response

Upvotes: 0

Views: 79

Answers (3)

Giovanni Botta
Giovanni Botta

Reputation: 9816

In Java, there is no such thing as manipulating a pointer directly. Any time you get a reference to an object, you are getting a copy to a reference, like a pointer to a pointer. For this reason if you do something like:

String s = "hello";
modify(s);
System.out.println(s); // still hello!

void modify(String s){
  s = s + " world";
}

You can't actually change the original reference s because the function is manipulating a copy to that reference. In the example above you would need something like this:

String s = "hello";
s = modify(s);
System.out.println(s); // prints 'hello world'

String modify(String s){
  return s + " world";
}

The same happens in your for comprehension. The variable tile is bound to the loop and is a copy of a reference in the array. The original reference (the array at the given position) can't be changed directly this way. That's why you need to call directly:

myTiles[i] = // something

Read this article for more information.

So the idiomatic way of modifying an array in java is something like:

for(int i = 0; i < myTiles.length; i++){
  myTiles[i] = new Tile(...); // directly reassigning the reference in the array!
}

Upvotes: 0

Reimeus
Reimeus

Reputation: 159754

The first loop makes a copy of each object and is equivalent to

for (int i=0; i < myTiles.length; i++) {
   Tile tile;
   ...
   tile = new Tile(...); // set local reference only
}

As elements in an Object array are null by default these would remain unassigned outside the scope of the loop. The original elements of the myTiles remain at their default null values

Upvotes: 1

Smutje
Smutje

Reputation: 18123

The for each loop uses an Iterator internally to fetch items from the collection and return you a new reference to a local variable containing each element - overwriting this reference is completely useless, as it is only valid for one for-loop and will be replaced on the next.

"Internally", your first loop would translate to

for (Iterator<Tile> iterator = myTiles.iterator(); iterator.hasNext;){
    Tile tile = iterator.next();
    tile = new Tile(number, getResources().getColor(R.color.puzzle_default));
    number++;
}

Upvotes: 1

Related Questions