3

assume i have code like this;

public void insert(Student[] stus)
{
    int count = 0;
    for(Student s: stus)
    {
    s.setId( bla bla);
    stus[count].setId(bla bla) // is this line needed?
    count++;
    }
}

So if i change anything on s from enhanced for loop, can i see the change in stus array also? How does enhanced for loop copy works in parameters or other things etc?

Mert Serimer
  • 1,217
  • 2
  • 16
  • 38

3 Answers3

6

The enhanced for loop doesn't create a copy of the elements of the Collection or array you are iterating over, and therefore s.setId() and stus[count].setId() would update the same Student instance.

stus[count].setId(bla bla) is not needed, as s.setId(bla bla) does the same.

Eran
  • 387,369
  • 54
  • 702
  • 768
2

Yes - s is just a variable which contains a value copied from stus. That value is a reference to an object - changes made via s will still be visible from stus. It's only the reference that's copied. So your loop can just be:

for (Student s : stus) {
    s.setId(...);
}

No need for the count at all unless it's part of the computation of the ID. If it is part of that computation, I'd just use a regular for loop instead:

for (int i = 0; i < stus.length; i++) {
    s.setId(/* some expression involving i */);
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • thank you for time and answer. Well, if that line needed, then i need to have a counter. You will ask why not then use normal "for"? It is because i am too lazy to write that long syntax when it is compared to enhanced for – Mert Serimer Jan 26 '15 at 08:38
  • @MertSerimer: But it's *not* longer when you separately need to declare `count` and then increment it. Basically, if you need to know which iteration you're on (and you're iterating over an array) I'd suggest using a normal `for` loop. If you *don't* need the iteration number, then the enhanced for loop is simpler, yes. – Jon Skeet Jan 26 '15 at 08:54
1

stus is a reference to an array object, that means that any change you perform on it within insert affects the actual parameter (the variable you used to call insert) as well as changes on its elements.

On the other hand, you don't need count as s is already a reference to the iterated element:

public void insert(Student[] stus)
{
    for(Student s: stus)
    {
        s.setId( bla bla);
    }
}
  • thank you for your time and answer. Well, if that line needed, then i need to have a counter. You will ask why not then use normal "for"? It is because i am too lazy to write that long syntax when it is compared to enhanced for – Mert Serimer Jan 26 '15 at 08:39
  • Java doesn't use pass-by-reference, *ever*. The reference is passed by value. That's not the same as pass-by-reference. In particular, if you write `stus = new Student[0];` in the `insert` method then that will *not* be visible to the caller, which it would with true pass-by-reference. – Jon Skeet Jan 26 '15 at 08:39
  • @JonSkeet I assume that for all purposes if you pass an object's reference by value the effect is like passing that object by reference. – Pablo Francisco Pérez Hidalgo Jan 26 '15 at 08:42
  • @PabloFranciscoPérezHidalgo: That's an incorrect assumption - and your description (as said by others, of course) is one which has confused many people in the past, who are used to real pass-by-reference. It's important to understand that the value of a variable in Java is *never* an object; only a primitive or a reference. Next, all arguments are passed by value - the initial value of the parameter is a copy of the value of the argument. At that point, everything is simple. – Jon Skeet Jan 26 '15 at 08:44
  • @JonSkeet I know the value of a variable in Java is not the value itself unless it is a primitive type. You can only access objects through their reference and, of course, when you pass an object as a parameter, its reference is passed by value. However, the effect is that if you change the object within the method you change the same object since what you copied was the reference and not the object. The effect is like passing the object by reference although it has been a referenced passed by value. – Pablo Francisco Pérez Hidalgo Jan 26 '15 at 09:01
  • @JonSkeet I have edited my asnwer to **strictly** adjust to how `Object` parameters are implemented in Java. I'd like to pinpoint that If are you have to implement a compiler for a language in which you can pass variables by reference, at low level, you will find yourself copying the value of a pointer, that is passing a pointer, call it reference, by value: http://stackoverflow.com/questions/2936805/how-do-c-compilers-actually-pass-reference-parameters – Pablo Francisco Pérez Hidalgo Jan 26 '15 at 09:05
  • @PabloFranciscoPérezHidalgo: How the language is implemented is not the same as how it's defined. All kinds of things happen under the covers to implement language semantics - but having a clear grasp of those semantics is important, IMO, and using one term as a shortcut for another is a bad idea. (As I say, I've seen several people confused by this in the past.) – Jon Skeet Jan 26 '15 at 09:34