Given: Class has no fields, every variable is local. littleString was created by refactoring bigString in Eclipse:
public String bigString()
{
StringBuffer bob = new StringBuffer();
this.littleString(bob);
return bob.toString();
}
private void littleString(final StringBuffer bob)
{
bob.append("Hello, I'm Bob");
}
The method littleString should not be passing the StringBuffer back, but yet is is. What kind of Black Magic goes on here? This is breaking all rules of encapsulation that I know. I'm in shock, words fail me.
-
littleStringisn't passing the object back -- it's just using the same object. Both the local variablebobinbigString()and the parameterbobinlittleString()refer to the same object, so if you change one of those objects, the changes will appear instantaneously in the other because they're both references to the same object.The issue is that
StringBuffers are mutable and have internal state associated with them. Some types of objects (such asStrings) are immutable, so you can safely pass them around as method parameters, and you know they won't ever get modified. Note that the addition of thefinalkeyword doesn't help here -- it just makes sure thatbobnever gets assigned to refer to a differentStringBufferobject. -
It's not passing anything back. It's modifying the StringBuffer you passed a reference to. Objects in Java are not passed by value.
whaley : Uhm, all parameters in java are passed by value: See http://www.yoda.arachsys.com/java/passing.html and http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#17996Chuck : Yes, but the value passed is a reference. The object is not passed by value — the reference still points to the same object. -
If you meant why does the string buffer get modified, it's because you were passing a reference to the string buffer, which allows you to call the public method append which modifies the string buffer object.
-
the answers above pretty much got it, except one little thing hasnt been mentioned: java lacks "const-ness", meaning you want an object to be unmodifiable.
"final" is close, but it still doesnt do the job properly. What the code snippet showed is the kind of error that can happen if you have mutable objects passed in as parameters to other methods. This can be fixed either by having immutable objects, or if there is some kind of new keyword added for deep const-ness.
Joachim Sauer : You can easily write immutable classes. I agree it's not the same as const-ness, but it gets you very far.WolfmanDragon : new String(bob.toString()) makes it unmodifiable. If bob ware a collection then Collections.unmodifiableCollection(bob) would have made it unmodifiable. Well it gets real close. According to Hardcore Java, nothing will make a mutable object totally unmodifiable.
0 comments:
Post a Comment