Java Forum / General / May 2007
Pass by reference or value?
getsanjay.sharma@gmail.com - 17 May 2007 20:31 GMT Hello friends, I am facing a lot of confusion over a simple issue of parameter passing. Just let me know what I have figured out is right or wrong:
"There is no pass by reference in Java. Everything is passed by value. In case of primitive types, a copy of the variable which holds its value is made and passed to the called function. In case of objects, a copy of the reference is made and passed to the called function. It is this reference variable which holds the actual reference to an object. Think of the reference variable as a container which holds a remote control, the remote being the object reference. When a reference variable is passed, this remote is passed by value hence the called function can manipulate the passed object. An exception here is the objects of class String since Strings in Java are immutable."
Looks good? Any interesting links would be appreciated.
Eric Sosman - 17 May 2007 21:11 GMT > Hello friends, I am facing a lot of confusion over a simple issue of > parameter passing. Just let me know what I have figured out is right [quoted text clipped - 12 lines] > > Looks good? Any interesting links would be appreciated. Partly sound, partly skewed.
You're right about argument passing: Java passes method and constructor arguments by value, period. Some arguments are primitive values and some are reference values; *none* are objects. If you are careful to distinguish references from objects, your quoted paragraph can be greatly simplified.
As for manipulating the objects whose references are passed: The method or constructor can *always* manipulate any object it has a reference to, understanding that "manipulate" need not imply "modify." There's no need to make special exceptions for String or other so-called immutable classes; calling str.length() or str.hashCode() is just as much a "manipulation" as calling any other method. (Indeed, hashCode() changes the internal state of a String object the first time it's called on that object: by computing and caching the hash code!) Immutability (to the extent it exists at all) has no interaction with argument passing.
 Signature Eric Sosman esosman@acm-dot-org.invalid
getsanjay.sharma@gmail.com - 18 May 2007 17:37 GMT > As for manipulating the objects whose references are passed: > The method or constructor can *always* manipulate any object it [quoted text clipped - 5 lines] > of a String object the first time it's called on that object: by > computing and caching the hash code!) How does and in what context is "manipulation" different from "modification"? Or is it that the functions called on the immutable object lend to its "manipulation"?
On May 18, 1:22 am, "Richard Reynolds" <richiereyno...@ntlworld.com> wrote:
> Pretty much, you can't write a swap function in java. > There are other immutable classes as well as String, plus you could write > your own of course. Sorry for taking this off topic, but how would you make a custom class immutable?
On May 18, 1:27 am, d...@dagon.net (Mark Rafn) wrote:
> The reference is copied, put on the stack, and passed to the method. In > exactly the same way as the 7 is copied, put on the stack, and passed to the > method. > > Stated another way, a new reference to the object is created and put on the > stack. Hmm..any links which can explain this very mechanism in-depth with respect to programming languages esp Java.
On May 18, 4:26 am, "Mike Schilling" <mscottschill...@hotmail.com> wrote:
> I think "container" is misleading, but not really incorrect. Perhaps you > mean "container" in that it can hold different reference values? Yeah, > that's OK. I heard that term on some site explaining variables. There it was said that "consider variables to be like a cup which can hold different values in different situations". Still thanks for the correction.
Patricia Shanahan - 18 May 2007 18:11 GMT ...
> Sorry for taking this off topic, but how would you make a custom class > immutable? ...
Write a class with the following properties:
1. All fields are private.
2. Only the constructors modify fields.
3. A constructor only modifies fields in the object it is constructing, not in any other instance of the class.
Instances can still be modified by reflection-abuse, but for all normal purposes they are immutable.
Patricia
Chris Smith - 18 May 2007 18:51 GMT > ... > > Sorry for taking this off topic, but how would you make a custom class [quoted text clipped - 12 lines] > Instances can still be modified by reflection-abuse, but for all normal > purposes they are immutable. I'd add:
4. Make either the class, or all of its methods, final.
 Signature Chris Smith
Patricia Shanahan - 18 May 2007 20:19 GMT >> ... >>> Sorry for taking this off topic, but how would you make a custom class [quoted text clipped - 16 lines] > > 4. Make either the class, or all of its methods, final. Good point. Without that, a subclass could effectively change a field, by overriding each method that uses it to use something else.
Patricia
Eric Sosman - 19 May 2007 21:07 GMT >> As for manipulating the objects whose references are passed: >> The method or constructor can *always* manipulate any object it [quoted text clipped - 9 lines] > "modification"? Or is it that the functions called on the immutable > object lend to its "manipulation"? "Immutable" is a fuzzily-defined concept. For example, it is common to say that String is immutable, even though some of its internal state can change after the String has been created (as by hashCode, for example).
One might say that the object is still "immutable" if the changes to its internal state are not "visible" outside the object itself. In the case of hashCode, one might argue that there is no way for the caller to detect whether the returned value was freshly-computed or was cached. And yet, there might in fact be a way to do so: If you made very careful timings of hashCode on a very long string, you might be able to observe that the first call took longer than subsequent calls; does this amount to a difference in behavior?
For that matter, it is in fact possible to "change" an existing String object in such a way that, say, charAt(0) returns different values at different times. (You use what Patricia Shanahan calls "reflection abuse" to find the char[] array underlying the String, and then you change the values of the array elements.) So it turns out that that String is only immutable in the face of "normal" operations -- which really says only that String cannot be changed unless you change it! By that definition, *every* class is "immutable:" just label any value-changing operations as "abnormal."
But let's go ahead and restrict ourselves to "normal" operations. Can we get visible changes in behavior from our immutable Strings?
// synchronized ("string") { Thread t = new Thread(new Runnable() { public void run() { synchronized ("string") { System.out.println("in thread"); } } }); t.start(); System.out.println("thread started"); t.join(); System.out.println("thread finished"); }
Clearly, the code's visible behavior -- its output -- depends on whether the first line is or isn't commented out. What is the difference? In one case the second thread can run to completion, and in the other it cannot. What is the reason for this difference? It has to do with whether the String "string" is or isn't locked -- that is, it has to do with the state of the supposedly immutable object "string". A change in the state of "string" produces a change in the behavior of the program; how can we keep straight faces while we talk about this state change and still say "immutable?"
Immutability is a useful concept, but hard to pin down with exactitude. "I know it when I see it," as Justice Potter Stewart said of another notion; the fact that he could do no better is evidence for the existence of things that seem easy to understand but prove hard to define. I believe "immutability" is one such.
 Signature Eric Sosman esosman@acm-dot-org.invalid
getsanjay.sharma@gmail.com - 20 May 2007 19:58 GMT > // synchronized ("string") > { [quoted text clipped - 10 lines] > System.out.println("thread finished"); > } Thanks to Eric and the others for their enlightening advice. What I don't understand here is why removing the commented out first line makes the program go in loop? Why is it not the case with the second synchronized block?
Sorry for asking simple questions.
Regards, STS.
Jim Korman - 20 May 2007 20:25 GMT >> // synchronized ("string") >> { [quoted text clipped - 20 lines] >Regards, >STS. The outer Thread running main is holding a lock on the object "string"
It then starts the runnable which attemps to gain a lock on the same object "string". Remember that in this case "string" has been "intern"ed so all "string" references are the same object!
The code isn't "looping", its deadlocked waiting for a resource that can not be released.
Jim
Mike Schilling - 21 May 2007 01:28 GMT >>> // synchronized ("string") >>> { [quoted text clipped - 24 lines] > The code isn't "looping", its deadlocked waiting for a resource that > can not be released. It's a subtle point that the two occurences of the constant "string" refer to the same object.
getsanjay.sharma@gmail.com - 21 May 2007 18:15 GMT Thanks a lot Mike and Jim for your explanation. It had slipped my mind that each object has a implicit lock which one must acquire to enter a synchronized block.
How would I use 'reflection abuse' to change the data inside a string. I tried using it but it gave me a 'security exception' saying that I can't modify the private field. I thought it was possible using reflection to do that. Any suggestions?
Thanks and regards, S T S
Richard Reynolds - 17 May 2007 21:22 GMT > Hello friends, I am facing a lot of confusion over a simple issue of > parameter passing. Just let me know what I have figured out is right [quoted text clipped - 12 lines] > > Looks good? Any interesting links would be appreciated. Pretty much, you can't write a swap function in java. There are other immutable classes as well as String, plus you could write your own of course.
The example I like to use to explain parameter passing is to pass a mutable Object, x, to a method, then in the method do x = new Whatever() and then show that x hasn't changed back in the calling method, but if I do x.setSomeValue(...) in the method show that the effect is seen outside.
Mark Rafn - 17 May 2007 21:27 GMT >"There is no pass by reference in Java. Everything is passed by value. Technically true. But confusing if you don't realize that object variables are already references, so passing them by value has the same effect as passing by reference in some other languages.
So you're passing a reference by value. How's that for confusing?
>In case of primitive types, a copy of the variable which holds its >value is made and passed to the called function. Variables aren't copied. Values are copied. The variable is 'x'. There's no 'x' passed to the method. The value is 7. That's copied and passed to the method.
>In case of objects, a copy of the reference is made and passed to the >called function. Right. The value of the variable (the reference) is copied and passed to the method.
>It is this reference variable which holds the actual reference to an object. Remove the word variable from that sentence. There's a reference to the object. It is assigned to a variable. The variable is said to be a reference to the object, in the same way as an int variable is said to be 7. But the variable and the value are different things.
The reference is copied, put on the stack, and passed to the method. In exactly the same way as the 7 is copied, put on the stack, and passed to the method.
Stated another way, a new reference to the object is created and put on the stack.
>An exception here is the objects of class String since Strings in Java >are immutable." There's no exception for String, or for Integer, or for any other immutable object. The reference is copied and passed. -- Mark Rafn dagon@dagon.net <http://www.dagon.net/>
Mike Schilling - 18 May 2007 00:26 GMT > Hello friends, I am facing a lot of confusion over a simple issue of > parameter passing. Just let me know what I have figured out is right [quoted text clipped - 5 lines] > copy of the reference is made and passed to the called function. It is > this reference variable which holds the actual reference to an object. Up to here, you're perfect.
> Think of the reference variable as a container which holds a remote > control, the remote being the object reference. When a reference > variable is passed, this remote is passed by value hence the called > function can manipulate the passed object. I think "container" is misleading, but not really incorrect. Perhaps you mean "container" in that it can hold different reference values? Yeah, that's OK.
> An exception here is the > objects of class String since Strings in Java are immutable." There are no exceptions. Strings being immutable merely limits what you can do via the remote control. You can't change them, but you can interrogate them in all sorts of ways.
sakcee@gmail.com - 18 May 2007 05:29 GMT On May 17, 12:31 pm, getsanjay.sha...@gmail.com wrote:
> Hello friends, I am facing a lot of confusion over a simple issue of > parameter passing. Just let me know what I have figured out is right [quoted text clipped - 12 lines] > > Looks good? Any interesting links would be appreciated. In almost all programming languages(I think), call to a method(function) results in a context pushed to stack. all the variables are passed as copies , hence by value. if the thing passed in a Java Referance, its copy inside the stack context will still be the same reference. same logic applies to C's pointer, referance, etc
Lew - 18 May 2007 13:33 GMT > In almost all programming languages(I think), call to a > method(function) results in a [quoted text clipped - 4 lines] > still be the same reference. > same logic applies to C's pointer, referance, etc I don't know about "almost" all, but a few major programming languages (C++, FORTRAN, to name two) support pass-by-reference semantics. If you weight the language by their significance the "almost" is canceled.
They don't copy the contents of the variable in such cases but the address. These languages don't necessarily distinguish variables from references with the rigor that Java does.
 Signature Lew
Mike Schilling - 18 May 2007 17:42 GMT >> In almost all programming languages(I think), call to a >> method(function) results in a [quoted text clipped - 12 lines] > address. These languages don't necessarily distinguish variables from > references with the rigor that Java does. C++ allows both "passing pointers by value" like Java and "passing by reference". The semantics of both are precisely defined. One thing I would not accuse C++ of is "lack of rigor".
Lew - 18 May 2007 23:25 GMT "Lew" wrote in message
>> These languages don't necessarily distinguish variables from references with the rigor that Java does.
> C++ allows both "passing pointers by value" like Java and "passing by > reference". The semantics of both are precisely defined. One thing I would > not accuse C++ of is "lack of rigor". You're right, "rigor" isn't exactly the concept I'm going for. "Rabidity", perhaps?
In any event, I didn't mean to imply lack of precision in C++ or FORTRAN, only the presence in Javamind of a very firm distinction not so prevalent in the mindsets of those venerable ancestors.
 Signature Lew
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|