• Post Reply Bookmark Topic Watch Topic
  • New Topic

Why doesn't the StringBuilder object show null?  RSS feed

 
Joe McTigue
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was reading through some java code and was wondering why, in the following code, the StringBuilder object isn't changed to null in class TestClass?


Please if anyone can explain this to me, it is driving me bats!

Thanks in advance.
 
Knute Snortum
Sheriff
Posts: 4274
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah yes, this will turn up in the exams for sure!

Java is always pass-by-value. That means that a copy of the object reference is created for the sb parameter (and the s parameter too). What you are doing in the method is simple setting this copy of the reference to null. Nothing "gets back" to the caller.

This is confusing because Java seems to sometimes act like pass-by-reference, since you have a copy of the original (caller's) reference to the object, you can make changes to the object that are "seen" by the caller. So when you do the sb.append(str), the caller's object is affected, because the copy of the reference still points to the caller's object.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Joe McTigue wrote:


The reason is that Java passes parameters by value, not by reference. In the code above you have to references to the same StringBuilder (one in the main method, and one in the testRefs method). When you assign a value to a reference it only affects that reference, and any other references are left unchanged.

You may be getting confused in this example because both references happen to have the same name. If I re-write the code and change the names it may make it more clear.



So as you can see now, the StringBuilder reference in the main method is not the same StringBuilder reference in the testRef method.

When you call the testRef method, the value of sb is copied into localParameter. The value that is copied is effectively a pointer to the StringBuilder object. This means that both references end up pointing at the same object (so when you call methods on that object in testRef the effect of those calls can be seen in the main method). However assigning the value of null to localParameter only affects localParameter and leaves sb unchanged.

Edit: Beaten by 30 seconds, boo! :P
 
Joe McTigue
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Isn't the StringBuilder object mutable?
...and wouldn't that mean the StringBuilder 'sb' reference stays the same?

What would be the difference if you used sb.delete(start, end) instead of sb = null?
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All references are mutable if they are not final. However if you mean are instances of the StringBuilder class mutable, then yes they are (or they wouldn't be much use as builders).

But something being mutable doesn't mean it stays the same, it means it can be changed. And it doesn't have anything to do with why setting the local parameter to null in testRef has no affect on the (different) local parameter in the main method.
 
Joe McTigue
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So if sb is only a local reference, then why does the following substituted for 'sb = null' affect the original value of sb and the previous 'sb = null' did not?

replace "sb = null" in previous code with:


I appreciate your answers and I am really attempting to understand this in a big way. :-)
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Joe McTigue wrote:So if sb is only a local reference, then why does the following substituted for 'sb = null' affect the original value of sb and the previous 'sb = null' did not?

replace "sb = null" in previous code with:


There is only one StringBuilder object (created in the main method). Both of the StringBuilder references are pointing to the same object. Imagine the object as a balloon, and the references are strings attached to the balloon. When you call the testRef method you copy sb into the parameter. This is like attaching a second string to the balloon.

When you set the local parameter in testRef to null that is like you cut the string with some scissors. That parameter in the method is no longer pointing to the object, but the other reference is left unaffected. This does not affect the internal state of the object, it just changes the value of the reference. But when you call the method on the object you are affecting the internal state of the StringBuilder object. This change can be seen from any references that you have attached to it.
 
Joe McTigue
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Mike, I actually get it now. :-)
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!