Pass by reference / pass by value

J

Jerry

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!
 
J

jan V

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 ;-)
 
M

Monique Y. Mudama

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.


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.
 
K

Kenneth P. Turvey

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
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 <[email protected]>

Currently seeking employment as a Java developer in the St. Louis area.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFDCjo23naBnF2rJNURAhIcAKC/+86LMfHE8qf5CT6JWTZTQMonpwCgsqif
9RjUgSOcvAmq7LjppZWZOmY=
=dBsO
-----END PGP SIGNATURE-----
 
J

John C. Bollinger

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.
 
C

Chris Berg

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
 
J

Jaakko Kangasharju

Chris Berg said:
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.
 
C

Chris Berg

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!!
 
P

Patricia Shanahan

Chris Berg wrote:
....
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_(computer_science) 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
 
C

Chris Berg

languages support different combinations of calling conventions. See
http://en.wikipedia.org/wiki/Parameter_(computer_science) 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.
 
P

Patricia Shanahan

Chris said:
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
 
K

Kenneth P. Turvey

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
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
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.
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 <[email protected]>

Currently seeking employment as a Java developer in the St. Louis area.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFDC1Eh3naBnF2rJNURAgC3AJ9QEjW03xn1uQ6lXcmWPZ7/fI2dXwCfbDgi
mrjmyIFX1vQcIS+dUhrKK1k=
=+bgW
-----END PGP SIGNATURE-----
 
B

blmblm

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


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.

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
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.
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?

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
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.

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 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.
 
R

Roedy Green

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.
 
L

Lasse Reichstein Nielsen

Roedy Green said:
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
 
J

jameshanley39

Jerry said:
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
 
J

jameshanley39

(e-mail address removed) wrote:

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

correction of self.

no such thing as #a or #p in C/C++. It's *a, or, *p
 
C

Chris Smith

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++).

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

jameshanley39

Chris said:
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++).

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top