Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Please explain this increment to me  RSS feed

 
Miles Williams
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay. I've come across a piece of code and I am totally baffled by how a certain field is being incremented.




Now. The output for this is:
0
1
2
3
4

I understand all the code in it quite well. It's all basic. Containers, generics, looping, foreach loop. What I DON'T understand though is how on each iteration of the foreach loop, the call to the method id() returns an incremented number. I am assuming it has something to do with the field "counter" in class Foo being static because when I made it non-static it didn't increment. I must have missed something WAAAY back when I started learning Java because I just don't get it. The id() method only returns the value of the id field in class Foo and that is the value of counter++. counter is not initialized, though I'm guessing it gets the default 0 when the Foo() constructor is run? Or do statics get initialized BEFORE the constructor is even run? Anyway. How does calling the id() method cause an incrementation? I'd understand if there was some code that tracked the number of Foo objects being created and incrementing for each one, but I cannot see how each time the id() method is called it returns an incremented value.
 
Jan Hoppmann
Ranch Hand
Posts: 147
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have to guess here, but I'd say every time you initialize a new object of Foo, it gets a new instance of id. Since id is counter++, the static counter is incremented each time you access it this way. This seems the most plausible explanation to me.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miles Williams wrote:counter is not initialized, though I'm guessing it gets the default 0 when the Foo() constructor is run?

No, it gets initialized when the class is loaded, and there is only one instance of counter no matter how many Foo objects you create. That's how static variables work. 'id', on the other hand, is an instance variable, so there will be a copy for each object.

I should add that the code looks like something dreamed up for the SCJP exam to explain the difference between static and non-static variables, and you should never do anything like it in real life.

Winston
 
Miles Williams
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmm.
If the field id was static I would understand, in THAT case then it would be that there is only one for the whole class not for each object of Foo that's instantiated and so each time a new Foo was created that value would be incremented IF it was incrementing itself. But its taking the value from counter and incrementing that AND id is final. I thought a final field COULDN'T have a new value assigned to it, sort of like a constant value. I'm so confused. Can someone please walk through the code for me and explain exactly WHERE the increment takes place and what causes it please??

Ok. We enter main()
Define a reference called fooList for an ArrayList of Foos then assign it to a new object of ArrayList of Foos.
Then a standard for loop is entered which goes though 5 iterations, on each iteration the add() method is called for fooList and passed a new Foo() constructor which is a default no-args constructor generated by the compiler.
Now we have an ArrayList of Foos with 5 Foo references in it.
Enter the foreach loop where we have a Foo reference f and we iterate through our previously populated ArrayList of Foos and with each index in that that we pass through to f and call the id() method on it and pass that into a println() method.

WHERE here do we get the increment?
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch.

Do you know what 'static' means when used on a variable in a class? It means that there is only one copy of the variable, which is shared between all objects of the class - unlink non-static member variables, where each object has its own copy of the variable.

That means that there is only one 'counter' variable, which is re-used by all Foo objects.

Indeed, as you suspected, 'counter' is not explicitly initialized, which means it will be initialized with the default value which is 0. It is initialized when the class Foo is used for the first time - it is not initialized each time you create a new Foo object. That's because it's a static member variable.

Each time you create a new Foo object, this line is executed:

It assigns the current value of 'counter' to 'id' and then increments 'counter'.

So, when the first Foo object is created, it's id is set to 0, then counter is set to 1.
When the second Foo object is created, it's id is set to 1, then counter is set to 2.
When the third Foo object is created, it's id is set to 2, then counter is set to 3.
Etc.

You have two for-loops in your code.

In lines 16 and 17, you create 5 Foo objects in a loop. They get their id's set as explained above, and the counter is incremented each time a new Foo object is created.

In lines 19 and 20, you loop through the list of Foo objects and print the id of each of them.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miles Williams wrote:WHERE here do we get the increment?

Look at line 4 because that's where you get it. 'id' needs to be initialised for each new object, and its initialiser also increments counter.

Winston

PS: Welcome to the Ranch. Miles.
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Reread Jan Hoppmann's post, which gives the correct answer. If there is any of it you can't understand, please tell us and we'll try and explain it. I think lost plausible is an unusual spelling of most plausible
 
Jan Hoppmann
Ranch Hand
Posts: 147
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Welcome to the Ranch

Reread Jan Hoppmann's post, which gives the correct answer. If there is any of it you can't understand, please tell us and we'll try and explain it. I think lost plausible is an unusual spelling of most plausible


I corrected that. Yes, you're right
 
Miles Williams
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the welcome.
And thank you for the replies.
Sorry on my op I made the mistake of asking whether the field was initialized when the object was created. In my second though I do state that being a static there is only one per class. I was changing around the access modifiers between the two fields in Foo and knew it had something to do with static.

But. From what you are saying, my confusion is coming from the initialization of id with counter++. Are you saying that is changing the value of the static field counter? That's the only plausible explanation but I was under the impression it was simply taking the value from counter incrementing it by 1 and assigning it to id. With counter remaining the same. Which is wrong by the looks of it.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miles Williams wrote:
But. From what you are saying, my confusion is coming from the initialization of id with counter++. Are you saying that is changing the value of the static field counter? That's the only plausible explanation but I was under the impression it was simply taking the value from counter incrementing it by 1 and assigning it to id. With counter remaining the same. Which is wrong by the looks of it.


Yes, your impression is incorrect. What the post increment operator does is return the current value from counter to be assigned to id, and then increment the counter variable -- hence, why it is called the post increment operator.

Henry
 
Miles Williams
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So. Would writing it as counter + 1 have a different effect and do what I thought was happening?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miles Williams wrote:So. Would writing it as counter + 1 have a different effect and do what I thought was happening?

If you mean that counter would then NOT be incremented, then yes. Also, all your Foo object would contain the same 'id' value (1).

Winston
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miles Williams wrote:So. Would writing it as counter + 1 have a different effect and do what I thought was happening?


This statement ...



is the equivalent of doing this ...



I assume that you want something like this...



Henry
 
Paweł Baczyński
Bartender
Posts: 2085
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:I assume that you want something like this...



Henry


I think OP wants something like:
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pawel Pawlowicz wrote:
I think OP wants something like:


As described by the OP...

Miles Williams wrote:I was under the impression it was simply taking the value from counter incrementing it by 1 and assigning it to id. With counter remaining the same.


I am assuming that when the OP said "counter remaining the same", it meant that it should not be changed, and not meant that it should be the same as id? Regardless, I think the OP should clarify.

Henry
 
Paweł Baczyński
Bartender
Posts: 2085
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I understood:
With counter remaining the same as the id

Yeah, some clarification would be nice.
 
Miles Williams
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes that's what I meant.
The value of counter remains unchanged.

It's not what I "want" I was just trying to figure out how the increment was being applied as it's not the way I would've wrote it.
And I was always under the assumption that the ++ and -- were simply shorthand for +1 and -1. That's where I lost track.
In my mind the expression id = counter++ to me was the same as id = counter + 1
That's why I thought counter wasn't being incremented. It's all good now. I see exactly what's happening.
Just not the way I would have gone about it. And not something I've seen done before.
 
Miles Williams
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh.
And thank you to everyone who replied. Very much appreciated.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miles Williams wrote:Just not the way I would have gone about it. And not something I've seen done before.

Probably because it's not really very useful.

The problem with static counters is that they only work for a session. As soon as you end your program, the counter is lost, and it will be set to 0 again the next time you run your program. What you may see is a static counter that is initialized from a file (or database) and then saved back when you close the program; but logic like that can be quite tricky, especially if more than one instance of the program can run at any given time.

And thank you to everyone who replied. Very much appreciated.

You're most welcome. Hope it helped.

Winston
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!