

Java is Pass-by-Value, Dammit - m0th87
http://javadude.com/articles/passbyvalue.htm

======
Edmond
Good post.... I am a Java developer with almost 10 yrs of experience and I
know I often make that mistake even on Job interviews:).... The problem is
that people used to Java tend to think more about the intuitive consequence of
passing by ref vs value. When a Java dev thinks of passing by reference he's
thinking: "I can alter the state of the reference and the changes would be
visible globally, including from within the calling context". In other words
Java devs think about altering arguments in terms of altering their state as
opposed to altering the reference which is just a numeric address to a memory
location. People who program in languages lacking object/class-like structures
are more aware of the need to use parameters both as arguments and return
values, something that is foreigner to Java programmers.

I haven't done any serious C++ programming in years and I have to admit the
examples you used to demonstrate your point; ie modifying the value of
arguments appears very strange to me now, I obviously did a lot of that when I
did C/C++ development but not having done it in such a long time it really
does seem like an unusually way of getting return values:)

------
runT1ME
Almost EVERYONE I've interviewed, including senior programmers, think that if
you do this:

    
    
       void nullThis(Object o) {
          o = null;
       }
       Object o = new Object;
       nullThis(o);
       System.out.println(o.toString());
    

throws a NPE

------
SeanLuke
Java is in good company. Lisp is also pass by value.

------
binaryfinery
Passing an object by reference is the same thing as passing an object
reference by value. It _is_ just semantics. Its not even splitting hairs. Its
demanding that his specific definitions are somehow more correct than any
other.

~~~
okmjuhb
This is not at all correct because passing by reference and value have defined
and distinct meanings. Consider the difference between C++, which has actual
pass by reference: void swap(int& x, int& y) { int t = x; x = y; y = t; }, and
Java: void swap(Integer x, Integer y) { Integer t = x, x = y; y = t; }. The
C++ version will result in changes to the variables in the calling function
and the Java version will not.

The real problem is that Java created needless confusion by calling its
pointers references for purely marketing reasons.

~~~
binaryfinery
No the real problem is that you fail to understand that Java gets to call
these things what ever it likes because language has context. And your example
fails to compare apples to apples. In Java Integer _is_ an object, but int is
not. You are confusing Java things with C++ things. As you can see, Java is
not C++, and so your C++ terms and definitions do not apply here. Thank you
for playing. Move along.

~~~
okmjuhb
"No the real problem is that you fail to understand that Java gets to call
these things what ever it likes because language has context."

This is silly; "pointer" and "reference" both had meanings before Java came
along. If Java called pointers "names" instead of "references" it wouldn't
mean that its function call semantics were pass-by-name either. And besides;
if your argument is that we should use the Java terminology to describe all
the aspects of Java under discussion, the fact that the all the Java designers
make explicit that the function call semantics pass references as values, not
objects as values.

"And your example fails to compare apples to apples. In Java Integer is an
object, but int is not. You are confusing Java things with C++ things."

The argument applies if you use int in place of Integer just the same; or if
you make a C++ Integer wrapper class analogous to the Java one. Any comparison
here will of course be apples to oranges because _C++ supports pass by
reference and Java does not_. The swap function is impossible to write in Java
because it requires allowing called functions to change the values viewed in
the caller, which is almost the definition of passing arguments by value.

"As you can see, Java is not C++, and so your C++ terms and definitions do not
apply here. Thank you for playing. Move along."

Leaving aside the childish and insulting tone, the definition of "pass by
reference" has nothing to do with C++; if the code were in perl it would still
be pass by reference, because "pass by reference" has a meaning that exists
outside of any particular programming language and describes a concept. Java
function calls are not part of that concept; "there is exactly one parameter
passing mode in Java - pass by value".

~~~
binaryfinery
In which case there is no such thing as passing by reference. Ever. In C++
when you "pass by reference", what actually happens is that the address of the
thing is taken, and a pointer is generated, and then that pointer is passed by
value. Do you see? Any argument you put forth to the contrary will involve
language specific features and conventions of C++. Your will have to claim
that because the C++ compiler does this for you, that makes it special. In
Java there are primitives and objects. Primitives are only passed by value.
Objects are passed by reference. If you pass an object as a parameter, and
then modify a property of the parameter, then it is the original object that
is modified. This, in fact, is the same as when you pass an Object in C++ by
reference. In contrast, in C++ you can also pass an object by value: the
entire object is copied onto the stack.

class Foo; void modify( Foo& x) { x.setBar(1);} ; <\- pass by reference in
C++.

class Foo; void modify( Foo x) { x.setBar(1);} ; <\- pass by reference in
Java.

Java spares you the & because Java _only_ passes by reference.

Again, to argue the contrary, simply because it passes an object pointer by
value, automatically, is to argue that C++ never passes by reference because
it too takes the address automatically.

The fact is that Java passes by reference exactly as C++ does. However, even
if this were not the case, it would also be completely acceptable for Java to
refer to what it does as pass by reference simply because it chooses too.
These things _are_ object references. If I pass a java object reference, is it
acceptable to say I'm passing by reference? If Java people want to say it is,
then it is. Will the world end, for example, because the word "heap" means two
different things in computer science? <http://en.wikipedia.org/wiki/Heap> OMG!
Who is _right_?

My point is basically summed up here: <http://xkcd.com/435/>

You are where the physicist is standing. You insist that Java biologists are
using your terms wrong while oblivious to the mathematician. You have your
abstractions. Java has theirs.

Of course, maybe you're the chemist, and I'm the physicist (I still write
assembly) and the hardware guys are the mathematicians. Whatever.

As for the insulting tone, yes its a character flaw. When someone makes a
statement like "I'm really tired of hearing folks (incorrectly) state
[whatever]", its insulting. Its especially insulting when its wrong. In an
ideal world I'd be able to respond without resorting to responding in kind,
but I'm flawed. Sorry. You're still wrong.

~~~
okmjuhb
The argument "well, passing by reference gets compiled to passing a pointer by
value so really there is no passing by reference" is silly because passing by
reference is a description of language semantics and function call evaluation.
Your argument applies just as well to the statements "there is no such thing
as lambda functions" or "there is no such thing as garbage collection" because
those language features also get converted into representations that don't
have either of them present.

The Java code you give isn't an example of passing by reference because, while
you can change the value that x points to in Java, you can't change x to point
to something different. No java function can change its arguments; the example
you gave has the java function changing something that its argument points to.

Your argument that Java people can call language features the same name as
distinct language features is: a. dumb, because it's just "words mean whatever
anyone wants them to mean", and b. doesn't come anywhere close to applying
here; the quotation at the end of my last response: "there is exactly one
parameter passing mode in Java - pass by value" is a direct quote from 'The
Java Programming Language'. _The authors of Java disagree with you_.

More from them: "All parameters to methods are passed 'by value'. In other
words, values of parameter variables in a method are copies of the values the
invoker specified as arguments. If you pass a double to a method, its
parameter is a copy of whatever value was being passed as an argument, and the
method can change its parameter's value without affecting values in the code
that invoked the method.

...

You should note that when the parameter is an object reference, it is the
object reference - not the object itself - that is passed "by value." Thus,
you can change which object a parameter refers to inside the method without
affecting the reference that was passed. But if you change any fields of the
object or invoke methods that change the object's state, the object is changed
for every part of the program that holds a reference to it.

...

Some people will say incorrectly that objects are passed "by reference." In
programming language design, the term pass by reference properly means that
when an argument is passed to a function, the invoked function gets a
reference to the original value, not a copy of its value. If the function
modifies its parameter, the value in the calling code will be changed because
the argument and parameter use the same slot in memory.

...

The Java programming language does not pass objects by reference; it passes
object references by value. Because two copies of the same reference refer to
the same actual object, changes made through one reference variable are
visible through the other. There is exactly one parameter passing mode - pass-
by-value - and that helps keep things simple."

Your last few paragraphs are beside the point; the question is not about which
languages offer which levels of abstraction; the point is that different
abstractions have different names and Java doesn't offer the abstraction named
"pass by reference".

~~~
binaryfinery
Perhaps I misunderstand the whole thing then. Tell me is this C++ code "pass
by reference" or not?

class Foo;

void Bar( Foo& somefoo) { ... }

