0

I was programming a plugin in Java and I wanted to set 4 different Location objects. Because in school(C++) they taught us to use [] and I like them (brackets), I decided to do that. Oh boy, I was wrong(or maybe it was just my mistake) I came up with this code:

Location[] pos = new Location[4]; //an array (I guess)
Location loc = e.getBlock().getLocation(); //to get the position of a block

and then I set it in a for loop to iterate trough them like this:

for(int i = 0; i < 4; i++){
    pos[i] = loc;
}

But! When I wanted to change any of the pos[x] variables, all of them changed. Could this be related to pointers or something? Anyways. I changed my code to do it like this

Location loc = e.getToBlock().getLocation();
Location loc1 = e.getToBlock().getLocation();
Location loc2 = e.getToBlock().getLocation();
Location loc3 = e.getToBlock().getLocation();

This code fortunately works, but how would I go with more variables, what if I wanted something like 200 of them? Or maybe a dinamic "array". You might be wondering why I said "array" in quotes, but I really have no idea how to call pos[] other than an array, even tho I know that an Array exists and it's something completely different.

tnw
  • 13,521
  • 15
  • 70
  • 111
MG lolenstine
  • 919
  • 1
  • 11
  • 32

5 Answers5

2

You have to create a new Location object at each iteration in the for loop.

Now you are using the same object in all the array slots. The 'loc' variable is a reference to the object in the heap, so changing it spreads the changes to all the array,

Davide Gualano
  • 12,813
  • 9
  • 44
  • 65
  • Thank you, exactly what I was looking for... That's what I didn't know... I thought that by doing pos[i] = loc I was setting the value of loc, but now I know that I was setting the Object... – MG lolenstine May 23 '17 at 15:34
1

They all changed because you set them all to be the same object: the one you assigned to loc. If you had put the call to e.getToBlock().getLocation() inside the loop, your 4 array elements would have been different objects.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
1

Right now your getLocation function is only being called once which creates a single object. Call it inside your for loop.

for (int i = 0; i < 4; i++) {
    Location loc = e.getBlock().getLocation(); //to get the position of a block
    pos[i] = loc;
}
sdasdadas
  • 23,917
  • 20
  • 63
  • 148
1

When I wanted to change any of the pos[x] variables, all of them changed

It's because you assign each element of your pos to same object. You are from C++ background, so you should have a knowledge about pointers. What you are doing is assigining a "pointer" to same object in all positions of pos.

what if I wanted something like 200 of them?

I am not sure if I understand you right. You can use an ArrayList which allows you to add elements dynamically, so you don't have to know its size in advance. Look at the docs.

gonczor
  • 3,994
  • 1
  • 21
  • 46
  • Thanks, I do have some limited knowledge to pointers, but the thing I was missing was that when I was doing pos[i] = loc, it was setting the reference to an object... And I thought it was setting the value... – MG lolenstine May 23 '17 at 15:36
  • 1
    Glad I could help with this :) – gonczor May 23 '17 at 16:25
1

Did you intend to assign for all the array items the same object loc?

If yes, here we go. As others suggest, you should call the function e.getBlock().getLocation() once each time you go through your loop. This gives different objects with the same value.

Another workaround is to copy the object, rather than only assign the reference. What I think about your problem is that you are mixing copying and assignment. When you assign loc to the array items in your loop

for(int i = 0; i < 4; i++){
pos[i] = loc;
}

you assign it by reference, as it an object and not a primitive data type.

This means that the array items, after you assigned loc, have a only a reference to a memory position, when you change its value via any reference, all other references will have the new value, expected behaviour.

If you intend to initiate all the items of your array to loc, you should deep/shallow copy it, i.e., not assign it by reference. See here for an explanation on difference between copy and assignment. Here is an answer for deep copy using serialization

Median Hilal
  • 1,483
  • 9
  • 17