Java Forum / General / September 2005
Pass by reference / pass by value
Jerry - 22 Aug 2005 20:00 GMT Is that true that Java pass primitive type by value when calling a method and pass object by reference?
If I pass a StringBuffer object to a method and append the strings to the StringBuffer object in the called the method. When the method returns, the original StringBuffer object in the calling method will be modified. Is that right?
Thanks a lot!
jan V - 22 Aug 2005 20:14 GMT > Is that true that Java pass primitive type by value when calling a > method and pass object by reference? No. You could read any book on Java (the language), or the Java Language Spec, and both would tell you everything is passed by value.
> If I pass a StringBuffer object to a method and append the strings to > the StringBuffer object in the called the method. When the method > returns, the original StringBuffer object in the calling method will be > modified. Is that right? That's correct ;-)
Monique Y. Mudama - 22 Aug 2005 20:31 GMT >> Is that true that Java pass primitive type by value when calling a >> method and pass object by reference? [quoted text clipped - 9 lines] > > That's correct ;-) You're trying to be purposely vague, aren't you?
To the OP: Jan is right. IIRC it's because you're not actually passing an Object; you're passing a reference, which is passed by value.
There. Clear as mud.
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Roedy Green - 22 Aug 2005 21:36 GMT >Is that true that Java pass primitive type by value when calling a >method and pass object by reference? see http://mindprod.com/jgloss/callbyreference.html http://mindprod.com/jgloss/callbyvalue.html
Kenneth P. Turvey - 22 Aug 2005 21:48 GMT > Is that true that Java pass primitive type by value when calling a > method and pass object by reference? Yes, exactly. Note that arrays are object types in Java.
> If I pass a StringBuffer object to a method and append the strings to > the StringBuffer object in the called the method. When the method > returns, the original StringBuffer object in the calling method will be > modified. Is that right? Yes.
- -- Kenneth P. Turvey <kt@squeakydolphin.com>
Currently seeking employment as a Java developer in the St. Louis area.
John C. Bollinger - 23 Aug 2005 05:47 GMT >>Is that true that Java pass primitive type by value when calling a >>method and pass object by reference?
> Yes, exactly. Note that arrays are object types in Java. No, not exactly. As others have already pointed out, Java has only pass by value. Also mentioned, but perhaps not quite as clear, is that Java doesn't pass objects at all, only references to objects (by value). Indeed, in Java you can *never* put your figurative hands directly on an Object: you can only manipulate objects via references. We are typically sloppy in our terminology on this point: we say we have a variable of type Foo or an array of Bar, when what we really have is a variable of type *reference to Foo* or an array of *references to Bars*. Similarly, we often say that we pass a Baz, when we really mean that we pass a reference to a Baz -- by value.
So what's the difference between passing an object by reference and passing a reference to it by value? It is a subtle distinction. The key difference is what happens if you assign to the parameter in which the argument was passed. Consider:
void doSomething(StringBuffer sb) { sb.append("How many roads must a man walk down?"); sb = new StringBuffer("So long, and thanks for all the "); //* sb.append("fish"); }
void doSomethingElse() { StringBuffer buf = new StringBuffer("");
doSomething(buf); System.out.println(buf); }
When doSomethingElse() is invoked, what do you expect it to print?
With pass by value, at the line marked (//*) above, all that happens is a reference to the new StringBuffer is assigned to the local variable "sb", which happens to have been initialized with the StringBuffer reference passed by the caller. This is quite invisible to the caller. Since the buffer was previously appended to via the reference passed by the caller, on return the caller sees the first append reflected via its copy of the reference, and prints "How many roads must a man walk down?". This is indeed what happens.
With pass by reference, however, the marked assignment would change the value of buf in doSomethingElse(), so that the original StringBuffer is lost. The second append would be visible, so the method would print "So long, and thanks for all the fish". This is not what happens.
 Signature John Bollinger jobollin@indiana.edu
Kenneth P. Turvey - 23 Aug 2005 17:38 GMT > No, not exactly. As others have already pointed out, Java has only pass > by value. Also mentioned, but perhaps not quite as clear, is that Java > doesn't pass objects at all, only references to objects (by value). OK, technically correct, but also of no value to the original poster. What exactly is the difference between pass by reference and passing a reference by value? How else would you pass by reference? This is a difference that's not really a distinction.
> Indeed, in Java you can *never* put your figurative hands directly on an > Object: you can only manipulate objects via references. We are [quoted text clipped - 3 lines] > Similarly, we often say that we pass a Baz, when we really mean that > we pass a reference to a Baz -- by value. Correct.
[Snip]
> With pass by reference, however, the marked assignment would change the > value of buf in doSomethingElse(), so that the original StringBuffer is > lost. The second append would be visible, so the method would print > "So long, and thanks for all the fish". This is not what happens. OK, I stand corrected. There is a difference between passing by reference and passing references by value. I guess I tend to think of them as equivalent because I have never worked in a language that does it any differently. In fact the way passing by reference is usually implemented is just the way Java handles it, passing a reference by value.
VB?
In any case, the original poster was trying to figure out whether he could modify an object passed into a method and have those modifications be visible outside the method (the usual definition of pass by reference). I told him he could.
If you are the original poster you should probably be aware of this distinction. You can change the contents of an object (reference) passed to a method and have it be visible outside the method, you cannot however change the actual identity of the object (what the object reference points to) passed to a method and have it be visible outside the method.
- -- Kenneth P. Turvey <kt@squeakydolphin.com>
Currently seeking employment as a Java developer in the St. Louis area.
blmblm@myrealbox.com - 24 Aug 2005 07:15 GMT >-----BEGIN PGP SIGNED MESSAGE----- >Hash: SHA1 [quoted text clipped - 7 lines] >by value? How else would you pass by reference? This is a difference >that's not really a distinction. In Java, this makes a kind of sense. However, other languages provide more alternatives ....
Consider the following three C++ functions:
void clear1(int x) { x = 0; } void clear2(int *x) { *x = 0; } void clear3(int &x) { x = 0; }
The parameter for clear1 is an int passed by value; "clear1(y)" doesn't change y. This is similar to how Java treats primitives.
The parameter for clear2 is a pointer-to-int passed by value; "clear2(&y)" (&y is a pointer to y) does change y. This is similar to how Java treats references to objects. As in Java, if the body of clear2 was "x = new int; *x = 0;" it would have no effect.
The parameter for clear3 is an int passed by reference; "clear3(y)" changes y. There is no equivalent in Java.
>> Indeed, in Java you can *never* put your figurative hands directly on an >> Object: you can only manipulate objects via references. We are [quoted text clipped - 19 lines] > >VB? No idea about VB, but the examples above show some of the possibilities in C++. Notice that C allows clear1 and clear2, but not clear3, so it (like Java) is strictly pass-by-value, but what is passed can be an explicit pointer. This allows doing things that can't be done in Java, such as passing a pointer to a pointer.
>In any case, the original poster was trying to figure out whether he could >modify an object passed into a method and have those modifications be [quoted text clipped - 6 lines] >change the actual identity of the object (what the object reference points >to) passed to a method and have it be visible outside the method. Your last sentence is true, and this is the important distinction to be made in Java.
Technically this is not pass by reference.
It might seem pedantic to keep saying that in Java, "Object obj" declares not an Object but a reference to an object, but in fact I think making this distinction provides a conceptual framework in which many things make more sense -- not only the behavior discussed here, but also why after writing
MyClass[] a = new MyClass[10];
you then have to write a loop setting each a[i] to new MyClass() -- because new MyClass[10] creates not 10 new MyClass objects, but 10 references to MyClass objects. That's not how it works in C++, and it's a major source of confusion for people coming to Java from C++.
YMMV, maybe, but I think it helps.
| B. L. Massingill | ObDisclaimer: I don't speak for my employers; they return the favor. Chris Berg - 23 Aug 2005 08:39 GMT >Is that true that Java pass primitive type by value when calling a >method and pass object by reference? This has been discussed sooo many times here that I concider it really just a brain fitness exercise to try to mix in with the discussion. (Just try this link: http://groups.google.com/groups?q=reference+value+java , around 70.000 refs)
But for the fun of it:
IMO, all the trouble with this topic comes from the fact that 'pass by reference' and 'pass by value' are terms from other languages, specifically C, where they are well-defined and easily understood. It's wrong to use them at all in Java when referring to objects (primitives is a different matter - 'pass by value' is quite suitable here, although there is a little twist with arrays).
The reason that the C-terms cannot be used is that object variables are declared and created differently than in C / C++. In C you can declare a variable as a struct, or as a struct*. This option does not exist in Java, well, at least not directly.
One example of what happens is that you cannot make a swap method. This won't work, of course:
void swap (int a, int b){ int c = a; a = b; b = c; }
I find this a bit of a nuissance sometimes, when a method wants to return more than one scalar to the caller; then you have to create a class to hold them.
But alas - who gets everything his own way?
Chris
Jaakko Kangasharju - 23 Aug 2005 09:10 GMT > IMO, all the trouble with this topic comes from the fact that 'pass by > reference' and 'pass by value' are terms from other languages, > specifically C, where they are well-defined and easily understood. No, both terms are much older than C, and apply to programming languages in general. Besides, C, like Java, does not even have pass by reference. Both use pass by value always.
> It's wrong to use them at all in Java when referring to objects That's just because you cannot pass an object to a method at all, so parameter passing conventions do not apply to them.
 Signature Jaakko Kangasharju, Helsinki Institute for Information Technology If you want a response, you must demonstrate familiarity with ordinal arithmetic
Chris Berg - 23 Aug 2005 10:45 GMT >That's just because you cannot pass an object to a method at all, so >parameter passing conventions do not apply to them. After teaching Computer Science and java programming for years, I have come to the conclusion that the 'pass by ...' term is not the right way to make students understand the topic.
Real understanding comes when you open the lid and reveal the technical details: That pointers are indeed present in Java (how else would you explain 'NullPointerException' ?). As soon at the student realises that a declaration of an object is in fact just a placeholder for an address (or a reference, if you wish), initially pointing nowhere, then everything falls into place, and the difference between for instance 'myString=="abc" and "myString.equals("abc") becomes intuitively clear. Then it is no problem to understand that all formal method parameters (scalars and objects alike) are copies of the actual ones.
Also, it seems that students with no prior programming experience find it much easier to comprehend this topic than old-timers, who tend to fit new knowledge into already known patterns.
I once met a senior programmer (Fortran) who asked me what the 'RAM' was actually used for. The whole idea that a variable in fact occupies one or more consecutive cells in the 'RAM', and that a pointer to the variable is in fact the (more or less physical) address of the first one of these RAM cells never crossed his mind. And he was certainly not stupid!!
Patricia Shanahan - 23 Aug 2005 15:26 GMT > After teaching Computer Science and java programming for years, I have > come to the conclusion that the 'pass by ...' term is not the right > way to make students understand the topic. That depends on what the topic is. Is the topic Java, or programming with Java as the main language?
> Also, it seems that students with no prior programming experience find > it much easier to comprehend this topic than old-timers, who tend to > fit new knowledge into already known patterns. I wrote my first programs in 1967 and got a full time programming job in 1970 so I probably qualify as an old-timer.
I had far less trouble understanding Java's calling conventions than many students, precisely because I have a rich collection of already known patterns into which Java fits just fine. Of course, sometimes one needs a new pattern, but that is far less frequent than new instances of old patterns.
It is only if you try treat Java references as something other than pointers, and Java's calling convention as something other than call-by-value, that there is any difficulty.
If the objective is to just teach Java, it does not matter whether the students learn about the concept of calling conventions or just learn what Java does in isolation. Indeed, it may take less time for them to just learn what Java does.
However, in the early 1970's I took a course on programming languages that used several languages to teach concepts such as calling conventions and formal grammars. I no longer use any of those languages. I still use the concepts, 30 years later, every time I need to learn another programming language. That course was far more valuable to me than any course that aimed only to teach a programming language.
Patricia
Patricia Shanahan - 23 Aug 2005 13:04 GMT ...
> IMO, all the trouble with this topic comes from the fact that 'pass by > reference' and 'pass by value' are terms from other languages, > specifically C, where they are well-defined and easily understood. > It's wrong to use them at all in Java when referring to objects > (primitives is a different matter - 'pass by value' is quite suitable > here, although there is a little twist with arrays). ...
I learned both terms, in a programming languages class, in the early 1970's, years before I even heard of C. If I remember correctly, they were illustrated with examples from Algol and Snobol. They are two of a set of technical terms for describing calling conventions. Different languages support different combinations of calling conventions. See http://en.wikipedia.org/wiki/Parameter_%28computer_science%29 for a list that includes all the ones I've ever heard of.
I don't see anything wrong with discussing any calling convention in connection with any language: "Java does not support call-by-name." is a meaningful, and true, sentence.
Patricia
Chris Berg - 23 Aug 2005 13:53 GMT >languages support different combinations of calling conventions. See >http://en.wikipedia.org/wiki/Parameter_%28computer_science%29 for a list >that includes all the ones I've ever heard of. Fine link, with a clear description, using not too many words.
>I don't see anything wrong with discussing any calling convention in >connection with any language: "Java does not support call-by-name." is a >meaningful, and true, sentence. The interesting thing is not how we, who do understand it, express the subject among us, the interesting thing is how to explain it to newcomers in a way that doesn't lead to more confusion than clarity. Simple as it may seem, that IS actually a rather difficult task.
It reminds me of a task given to the readers of a Danish Engineers' magasine some years ago: Explain, using only 10 lines of text, why a mirror reverses left and right, when it does not reverse up and down. There were thousands of attempts, but none seemed to quite get it right.
Roedy Green - 24 Aug 2005 09:04 GMT > If I remember correctly, they >were illustrated with examples from Algol and Snobol Remember Algol's strange calling convention where you could pass in an expression as a parameter, and it was evaluated every time the variable was mentioned in the method, a very literal macro-like interpretation of parameters.
Calling conventions have become simpler over the years. At the same time the average size of methods has shrunk.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com
Lasse Reichstein Nielsen - 24 Aug 2005 17:49 GMT > Remember Algol's strange calling convention where you could pass in > an expression as a parameter, and it was evaluated every time the > variable was mentioned in the method, a very literal macro-like > interpretation of parameters. That's traditionally called "call-by-name". It's also quite inefficient, since a function like f(x) = x+x with call-by-name calling convention will evaluate its argument twice, so f(longComputation()) takes twice as long as for call-by-value.
On the other hand, it has an advantage if the argument isn't used, so g(x) = 42 is as efficient as possible by never evaluating the argument.
An intermediate version is "lazy" evaluation of arguments, as used by langauges like Miranda and Haskell. The argument is only evaluated if it is used, and then the value is cached for later use. On the other hand, that requires updating a state to store the cached value, which is overhead if the value is only used once. You just can't win :(
> Calling conventions have become simpler over the years. At the same > time the average size of methods has shrunk. These days, call-by-value and static scope is the default (thank $deity), but call-by-reference *is* available in a modern language like C#.
/L
 Signature Lasse Reichstein Nielsen - lrn@hotpop.com DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html> 'Faith without judgement merely degrades the spirit divine.'
jameshanley39@yahoo.co.uk - 09 Sep 2005 14:56 GMT > Is that true that Java pass primitive type by value when calling a > method and pass object by reference? everything is passe by value. Even objects(which are references) are passed by value.
IT confused me for a long time. But I am clear now.
There are 3 aspects here to each variable.
1 A Reference to a memory location 2 The value in the memory location
if the value (aspect 2) is a ref to an object. Then 3 (3rd aspect) is the Object. (This doesn't apply to primitive types. only object types).
**Java does not let you refer to Aspect 1.**
String a="strA"; String b="strB";
so variable a points to a string object. and variable b , points to a different string object.
a=b;
In java, this copies aspect 2, of b (the value of b), into a.
So a points to whatever b points to.
a is not an alias for b. Because we weren't copying aspect 1 of b into a's aspect 1. I.e. We weren't reassigning 'a' to the memory location of 'b'.
If we change what 'a' points to, then 'b' still points to whatever b points to. Becuase we only made them point to the same place. We didn't make them aliases for each other. They sit at dfif memory locations.
If, you change an aspect of the object that 'a' points to, then it will change the object that 'b' points to, becuase they are pointing to teh same object. since we did a=b.
THe concept is far far clearer in the programming language C, since C lets you refer to any aspect.
I do not know C. But apparently in C Given a variable , a
&a = memory location of a
#p = the value in the location that a points to. i.e. whatever a points to
a = the value of/in a
jameshanley39@yahoo.co.uk - 09 Sep 2005 15:04 GMT <snip>
> THe concept is far far clearer in the programming language C, since C > lets you refer to any aspect. [quoted text clipped - 8 lines] > > a = the value of/in a correction of self.
no such thing as #a or #p in C/C++. It's *a, or, *p
Chris Smith - 09 Sep 2005 15:25 GMT > everything is passe by value. Even objects(which are references) are > passed by value. > > IT confused me for a long time. But I am clear now. I might suggest some different language, though. It's certainly NOT true that objects are references. You might instead put it like this:
- All parameters in Java are passed by value. - Parameters may be either references or primitive types. - You CANNOT pass an object. Instead, you must pass a reference that points to that object.
This is superficially similar to passing an object by reference, but there are important differences... such as the fact that using the parameter on the left side of an assignment won't affect the value of anything in the caller's stack frame.
In fact, as a general rule, there is NO EXPRESSION, ANYWHERE, EVER in Java that actually represents an object. Expressions always resolve to primitive types or references. Objects are used incidentally by certain statements, but all values that are directly manipulated by a program are references or primitives. This is an important difference between Java and other languages (notably, C++).
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
jameshanley39@yahoo.co.uk - 09 Sep 2005 17:35 GMT > > everything is passe by value. Even objects(which are references) are > > passed by value. [quoted text clipped - 27 lines] > Chris Smith - Lead Software Developer/Technical Trainer > MindIQ Corporation Thanks for the correction.
is it ok to say. The value of an object variable is a reference / object reference An object variable contains a reference / object reference.
I agree. I was wrong to say an object was a reference.
To further distinguish between object and object reference.
java lets you manipulate the object e.g. obj.field1=3; But doesn't let you pass the object.
It lets you pass an object reference(by passing an object variable by value).
java lets you reassign a variable with a new object reference. and display the object reference. but doesn't let you do arithmetic on it , 'add one to it'.
And java doesn't give any access at all to &a. i.e. the reference of the location where the object variable resides.It doesn't let you see it, let alone pass it(pass by reference), or change it.
Roedy Green - 09 Sep 2005 19:08 GMT >> Is that true that Java pass primitive type by value when calling a >> method and pass object by reference? See http://mindprod.com/jgloss/callbyvalue.html http://mindprod.com/jgloss/callbyreference.html
I don't have an entry on call by name.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
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 ...
|
|
|