
Java is Pass-by-Value, Dammit - xvirk
http://javadude.com/articles/passbyvalue.htm
======
nickbauman
Well the way I've always thought of it is that Java passes "references by
value". Meaning the target method receives a _copy_ of the pointer, not the
actual pointer. So the result of newing up the parameter inside the target
method doesn't affect the original, because you're just making the pointer
point to a NEW memory address. On the other hand, mutating the parameter WILL
affect the original object, because a copy of a pointer still points to that
object from the caller.

~~~
cbd1984
> Java passes "references by value". Meaning the target method receives a
> _copy_ of the pointer, not the actual pointer.

Which is exactly how C does it. I don't see how this is a difficult enough
concept to grasp that we need an article explicitly pointing out how Java is
just like C in this respect.

~~~
learc83
Not everyone knows C. A large percentage (maybe even the majority) of
programmers who graduate from Java schools don't know C very well at all. For
them, "it works just like C" is an insufficient explanation.

~~~
tedunangst
"It works just like Python"

~~~
_ZeD_
Storically, python devs says the python language use "pass-by-name"

~~~
icebraining
How so? Reading [1] on pass-by-name, I don't see how it applies to Python,
which evaluates the function arguments before passing them.

The example given would be, in Python,

    
    
      def double(x):
        x *= 2
      a = [4]
      double(a[0])
    

If Python was pass-by-name, a would now be [8], but it's actually still [4].

[1]
[http://www.cs.sfu.ca/~cameron/Teaching/383/PassByName.html](http://www.cs.sfu.ca/~cameron/Teaching/383/PassByName.html)

------
AnthonyMouse
So to summarize, you have a Java function:

    
    
      public void f(Foo bar) { ... }
    

Which is the equivalent C++ function?

    
    
      void f(Foo bar) { ... }
      void f(Foo& bar) { ... }
      void f(Foo* bar) { ... }
    

It's the last one. Java passes everything by value, but non-primitive objects
in Java are actually pointers (which Java inaccurately calls references), and
the _pointer_ is passed by value.

~~~
wspeirs
Why is it inaccurate to call it a reference in Java?

You don't dereference a variable in Java to access it, so that would make me
think reference, not pointer.

~~~
jjnoakes
By you do deference object variables in Java. What do you think the "."
operator does?

~~~
wspeirs
Ah, true... so what is the difference between a reference and a pointer then?

~~~
jjnoakes
It depends on which definition of "reference" you are talking about.

Pass-by-reference and C++ references are basically the same - aliasing without
requiring dereferencing via an operator.

Java object references are like C++ pointers.

Java is pass-by-value (no aliasing) for all values (ints, bools, object
references etc). Java has no object values.

------
zvrba
Of course it is. It says so in the language spec, and even in the official
tutorial here:
[http://docs.oracle.com/javase/tutorial/java/javaOO/arguments...](http://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html)

Swap is a nice litmus test.

To people who claim that Java doesn't have pointers, I counter-argument by the
fact that you can make a circular doubly-linked list in Java. Thus, a
reference is a pointer though with lesser capabilities than in C++. In
contrast, you cannot make a circular doubly-linked list with C++ references
which are object aliases.

Actually, I have the following analogy: pointer ~ symbolic link; reference ~
hard link.

Java's references are misnamed.

~~~
tomjakubowski
> Java's references are misnamed.

That's silly. Why should every other language adhere exactly to C++'s
definition of a reference? 'Reference' as a concept exists outside of computer
programming and Java isn't wrong to repurpose the term in a different way than
C++.

Consider also that C++ has 'dependent types', despite pretty much no
relationship to the more well-known definition of dependent types. There are
only so many ways to name something.

~~~
evincarofautumn
There are also two uses of “dependent” in C++: the resolution of a name can
depend on a type parameter, so you have to specify whether you want to treat
it as a type name; and a type can depend on (compile-time) values. The former
has nothing to do with dependent typing, but the latter does!

------
lucio
This topic (I do not know why) raises some serious emotion-based responses on
coders. The other topic I know will cause almost a religious flame-war is the
philosophical meaning of "null" in the SQL arena.

I've tried to add some insight why the OP hears (so many) >folks (incorrectly)
state "primitives are passed by value, objects are passed by reference"

What I believe was my constructive addition to the topic, seems to deserve
only downvotes. I'll make a reminder to not participate again in this kind of
topics.

~~~
flomo
> This topic (I do not know why) raises some serious emotion-based responses
> on coders.

I saw the title on HN, and was like "uhhh, no shit, why is this here?". Then
surprisingly, it all of a sudden it has 80 points and almost 50 comments
debating the details. I don't think there's any actually real debate on how
Java actually works, this must be a purely linguistic. Or as you say,
"emotional".

SQL NULLs, on the other hand, is a real philosophical war. One which the wrong
size is clearly wrong and need to be crushed into ashes underneath our boots.
We are not debating jargon, we are defining databases which could certainly
outlive our sons and daughters!!!! .. Ok, sorry. But I just don't think it's
good comparison with students who just don't really get Java. Database design
is largely a matter of opinion, Java method calls are not.

~~~
probably_wrong
It is definitely emotional for me: I remember reading yet another of these
"java is not pass by reference" posts, and the title stuck for some reason. So
next time I wrote a Java function (long afterwards), I modified a list
received as an argument inside a function, and could not understand why my
original list was modified.

I honestly feel that these posts titles are just trying to pull my leg. "Java
passes everything by value!" "Really? And which value is being passed?" "The
reference, of course!".

~~~
jjnoakes
So instead of programming based on vague recollections of blog titles, you
should strive to understand the language you are writing in, so that you don't
make those mistakes.

Reading the content of the articles, doing some research, and actually
understanding what is happening in the language are all good steps to consider
taking.

------
furyofantares
The confused terminology isn't related to function calls. In Java, objects are
not values.

The confused terminology originates before you get to function calls -- you
can't ask "are objects passed by value?" without first considering objects as
values. Objects can't be stored in variables and objects cannot be the result
of an expression. x = y does not copy an object y into an object x because
objects are not values -- x and y are variables and they can only hold values,
which objects are not.

------
Osiris
I work full-time in JavaScript and I've always thought of JavaScript as a
pass-by-reference but this article made it clear that JavaScript is pass-
reference-by-value. The `swap` function from the article doesn't swap the
variables outside of the function.

~~~
jacquesm
javaScript != java...

~~~
rcconf
The behaviour of JavaScript is equivalent for references. (Call by sharing)

------
DonHopkins

      From: James Gosling
      Date: 1/13/11
    
      Don Hopkins wrote:
    
      >Hey I know it's 2011 and we're living in the future and all that, but
      >there still seems to be some confusion and debate about a matter I
      >thought was perfectly clear: Is Java pass by value or pass by
      >reference? 
    
      Depends on your terminology.  But it's kinda both.  It's pass-by-value for
      everything, with the twist that for class instances, the thing that's 
      passed-by-value is the pointer to the object, so it behaves like 
      pass-by-reference.
    
      From: Don Hopkins
      Date: 1/13/11
    
      Reminds me of the controversy about Niklaus Wirth's name:
    
      "Whereas Europeans generally pronounce his name the right way
      ('Nick-louse Veert'), Americans invariably mangle it into 'Nickel's
      Worth.' This is to say that Europeans call him by name, but Americans
      call him by value." - Introduction by Adriaan van Wijngaarden at the
      IFIP Congress (1965).
    
      It seems to be a consequence of pretending pointers don't exist -- you
      also have to pretend you have variables with object values and
      references, but you still can't write a swap(a, b) function. If you
      think of Java object values as pointers, then it's obviously passing
      references by value. But if you don't believe in pointers and think of
      variables as containing objects, then it's obviously passing objects
      by reference, but your view of the world is an illusion, because it's
      really implemented with pointers.
    
      Or is it??? Someone suggested a Magic Elves theory, which helps a lot
      of other stuff to make more sense.
    

Here's the discussion from 2011 about this issue that prompted me to ask James
Gosling for a clarification. You can see that many people were VERY confused,
and extremely fanatical about maintaining and spreading their confusion, in
spite of the fact that it directly contradicted the Java spec and the inventor
of Java himself.

Java is PASS BY VALUE.

[http://www.theserverside.com/discussions/thread.tss?thread_i...](http://www.theserverside.com/discussions/thread.tss?thread_id=61622)

~~~
lucio
The man says:

>But it's kinda both. It's pass-by-value for everything, with the twist that
for class instances, the thing that's passed-by-value is the pointer to the
object, so it behaves like pass-by-reference.

So he's saying: We call them all "chickens", but some of them walk like a duck
and quack like a duck, so they're basically ducks.

You can't extract from that quote "THEY ARE CHICKENS" (all in caps)

When he says "kinda both" and "it behaves like pass-by-reference" I read some
"subtle" hints saying that he thinks that basically class instances are
passed-by-reference.

~~~
jjnoakes
Except they don't completely behave like they are passed by reference (see
swap in the article). It is only ever correct to say "they behave like they
are pointers which were passed by value".

Continuing to say "they act like references" is wrong and how this mess keeps
perpetuating.

------
viraptor
I gave up on this... It's explicitly said in the Java standard that the
language is pass-by-value. On one occasion I've been told that the standard
must be wrong then. Some people just don't want to accept reality if it
doesn't match their interpretation of definitions. :-(

~~~
kremlin
Calling it "pass by value" without qualifying that, for objects, it passes the
reference by value, is very confusing.

~~~
viraptor
But these are completely separate things. You can have any mix of those (c#
actually has all):

\- Pass by value, values hold object references. (java, c# objects)

\- Pass by value, values hold objects. (c# structs)

\- Pass by reference, values hold object references. (c# inout parameter,
passing object)

\- Pass by reference, values hold objects. (c# inout parameter, passing
struct)

~~~
agricola
I'm not really sure what point you are trying to make here.

In general, the whole thing about passing a reference by value is just BS.
What you need to ask is, "What am I passing to the function?"

If you are passing an object, and Java (or whatever language you are using)
determines a reference (memory address or whatever), then passes that
reference to the function, then you are, by definition, passing an object by
reference. The important thing to focus on in this argument is, "What am I
passing?" The answer for this scenario is that the programmer is trying to
pass the object itself. Who cares about the address / location of the object.

If you decide to pass the reference explicitly, then you are passing a
reference, not the object. This would be like explicitly passing a pointer in
c++, and is apparently a controversial topic when it comes to Java. A
reference will nearly always (I can't actually think of a case where it isn't)
be a primitive, and therefore, be passed by value.

For argument sake, say I'm wrong about all this. My question would be, "What
would it look like to pass an object by reference, and how does that differ
from what is currently happening?"

~~~
viraptor
The point was, that there is a language close to java which can pass objects
by value or by reference. (It passes object references by value or by
reference if you want to call it like that)

To pass an object by reference, it looks exactly like C#'s out/ref parameter.

    
    
        void function(ref SomeClass arg) {
            arg=null;
        }
    
        var a=new SomeClass();
        function(a);
        // now a is null
    

Which is different from what happens without ref. (or by default in Java)

------
carsongross
Java hides the pointer, which is what confuses people.

Maybe we shouldn't be shitty about that, since it doesn't really matter too
much.

Just a thought.

------
mml
This entire thread makes me want to die. Please, do not speak of this again.

~~~
jjnoakes
Top notch contribution.

------
judk
The terms are not precisely enough to give meaning to cross-language
comparisons. Within a single language like C++, you can usefully differentiate
the various ways to pass references and data.

~~~
ta82828
I disagree. The question of whether or not you can write a _swap_ function as
described in the article is fairly precise.

------
moogly
FWIW, in .NET land, we tend to say "pass-by-reference-by-value".

~~~
MaxGabriel
I call this "pass by pointer copy". Does anyone know if that's a term people
use, or did I just invent it? I can only find one other person mentioning it
when I google for "pass by pointer copy" (in quotation marks for the exact
match).

~~~
jeff_marshall
No,that's completely natural (if verbose). This is from someone coming from a
C background, FWIW.

------
knappador
Novice Java programmer reads title, mutates Java object inside function, later
notices side-effects, and curses author of the title.

Second novice Java programmer reads title, wants to pass objects into
functions, wants to avoid expensive stack copy and writes &myObject, gets
compiler error, Googles "Java pointer," and curses author of the title.

Lesson learned: author of title is either unaware of the consequences such an
interpretation will cause or seeks cursing as a source of attention.

~~~
learc83
Novice Java programmer doesn't read title attempts to assign a new object to a
variable inside a function, doesn't work, curses Java tutorial that said
objects are pass by reference.

~~~
knappador
When in C, Python, Java, JS, or anything else does reassigning a variable from
the function sig _ever_ work? The symbol is in-scope. Even when overwriting
the pointer location in C, you don't just assign; you de-reference _and_ copy
over the memory that was there. A novice _programmer_ would make this mistake,
not a novice Java programmer.

------
twic
I remember this being a hot topic on usenet back in the '90s. It's great to
see it getting an outing today, and inciting equally as vigorous argument!

~~~
jtheory
Is there any _useful_ argument to be had around this, for pragmatic purposes?

No one disagrees about what Java is doing here (that I know of).

Naming is a problem if people are writing bugs due to the poor explanation.

But I can't think of the last time I've actually seen bugs caused because
anyone who thought that, for example, a swap() method would work in Java.

It's something that brand-new developers might muddle up, but usually they'll
learn how it works within the first year, no? If they keep track of how to
treat primitives vs. objects in methods by saying "Java passes primitives by
value, Objects by reference", and that works for them, that's okay. I think a
senior dev should know a bit more about what's really going on, but I'm not
waste the time of a mid-level programmer because, even though this code is
correct, I want to talk for 20 minutes about the _reason_ why it's correct
wasn't worded quite right.

I'm far more likely to see bugs caused by people misunderstanding Java's auto-
boxing/unboxing of primitives for method calls ("how the _devil_ is this line
throwing a NullPointerException?").

------
agricola
I think people are reading way too much into what a reference is. In c++, it
has a very specific meaning, but in Java it has a slightly different
definition.

In c++, the only difference between a reference and a pointer is in the
dereference syntax, and that a pointer can be reassigned. In the background,
the variable is a pointer in both cases. It is simply syntactic sugar.

Another thing some people are mixing up is the entire philosophy between pass-
by-reference and pass-by-value. The ability to write a simple swap function
does not accurately demonstrate what a language is doing. It is quite simply
whether or not the compiler creates a copy of the ___object_ __(not a copy of
the address / pointer / reference). If, in the background, Java passes an
address / pointer / reference (the word makes absolutely no difference), when
the programmer is attempting to pass an object, that is the definition of
pass-by-reference regardless what arbitrary word I want to name the
referencing value. Yes, the pointer is a copy of the previous pointer, but
that's not the explicit value that the programmer cares about.

Yet another comparison to c++: the same thing happens with pass-by-reference
in c++. If a function has the prototype:

    
    
        void foo(Dog& d);
    

and I pass a Dog object in a call similar to:

    
    
        Dog d("Spot");
        foo(d);
    

then, in the background, it is going create a reference (i.e. the address),
and copy it on the stack. In my foo() function, the argument is simply already
dereferenced (I don't have to treat it like a pointer).

TLDR...

If you pass an object to a function, and operations performed by that function
affect the original object, it is pass-by-reference. Period.

------
TazeTSchnitzel
PHP unfortunately has the same issue because it copied Java's terminology to
describe object reference values (introduced in PHP 5), yet it has always also
had "references" which are _actually_ pass-by-reference.

To demonstrate, object references/pointers/whatever:

    
    
      $foo = new Foo(); // $foo
      $foo2 = $foo;
      $foo2->x = 3;
      // $foo->x is also 3 now, $foo and $foo2 point to the same Foo object
      // that is, $foo and $foo2 both contain an object handle/pointer/reference/whatever that points to the same Foo object
    

PHP references:

    
    
      function swap(&$a, &$b) {
          $temp = $a;
          $a = $b;
          $b = $temp;
      }
      $a = 3;
      $b = 2;
      swap($a, $b);
      // $a is now 2, $b is now 3

~~~
Terr_
The only reason I use @-refs anymore is because of PHP copying arrays on
assignment (shallowly, lazily.) In addition--unless you do everything in a
super-functional way--you need to unset() each &-ref to prevent latent bugs
later in the same scope.

It's an unfortunate situation, and it gets worse when you add array-like-
objects into the mix, which look exactly like "normal" arrays up until the
moment everything explodes into WTFs.

------
solipsism
You can absolutely make a swap for reference types in Java. Here:
[https://gist.github.com/anonymous/d3b4b3bcacb478896ef2](https://gist.github.com/anonymous/d3b4b3bcacb478896ef2)

This is analogous to a C++ swap(Type&,Type&). The main difference is that C++
provides a default assignment operator for types, meaning you don't have to
provide _Assign_ yourself. A smaller difference is that the temporary instance
can be created on the stack in C++ but not in Java.

For primitive types it's absolutely true that you cannot implement swap
(unless you were to have created that value type in a reference-type wrapper).
It's misleading to say you can't do so for reference types.

~~~
jjnoakes
This is not the same swap.

The article (and the correct pass-by-reference litmus test) swaps the values
of the variables as the caller sees them, using operations inside the swap
routine.

Your example swapped the contents of the pointed-to objects, but did not
change the values of the variables a1 and a2.

If you want to see the difference, assign a1 to a new variable a3 before the
a1/a2 swap call. A real pass by reference swap will end up with a3 == a2, and
your example ends up with a3 == a1.

~~~
solipsism
Yes it is the exact same swap. Either behavior (what you call a3 == a2 and a3
== a1) is possible in either C++ or Java, depending on what you mean by
"assign a1 to a new variable a3". Your confusion is surely that C++'s assign-
by-value looks like Java's assign-by-reference. Again, either behavior is
achievable

May I invite you to write some code and see for yourself? Here:

C++ Swap (what you and the article call the litmus test):
[https://gist.github.com/anonymous/06b9251a37008d158f59](https://gist.github.com/anonymous/06b9251a37008d158f59)

Java Swap (exactly the same thing):
[https://gist.github.com/anonymous/d57d272579079b4e9ee8](https://gist.github.com/anonymous/d57d272579079b4e9ee8)

These programs don't only output the exact same thing, they do exactly the
same thing (except the differences I noted above, about the default copy
assignment operator being implicit in C++, and about C++ putting the temp
variable on the stack instead of the heap).

~~~
jjnoakes
No, it isn't the same swap. If you actually understand what is going on, you'd
realize it.

> May I invite you to write some code and see for yourself?

Sure. I've fixed your examples so they are analogous to each other and added
the check that I described in my previous post.

C++:
[https://gist.github.com/anonymous/9c66999844afcab15eeb](https://gist.github.com/anonymous/9c66999844afcab15eeb)
Java:
[https://gist.github.com/anonymous/bac324b3f3c13f263e14](https://gist.github.com/anonymous/bac324b3f3c13f263e14)

~~~
solipsism
Edited because I responded before reading your "fixes" correctly.

~~~
solipsism
Wait. This is even crazier than I thought. I just looked closer at your
"fixes". You're passing a pointer by reference? You're really stretching.

Look at the article. It contains c++ code for a swap litmus test. It doesn't
look like your "fix". Your swap is not the _traditional swap(a,b) method
/function_ called for by the author.

Here is a traditional swap function:
[http://www.cplusplus.com/reference/algorithm/swap/](http://www.cplusplus.com/reference/algorithm/swap/)

~~~
jjnoakes
Yeah, no kidding. You can't write the C++ by-value swap (without pointers) in
Java because Java is only pointers. It has no non-pointer objects.

The C++ version I posted shows you exactly what the Java object model is
doing, except since you can't take in references to the variables (Java has no
pass-by-reference), you can't do the pass-by-reference swap. The only swap you
can do in Java is the pass-by-value swap.

The C++ pass-by-value swap (using pointers like Java requires) looks like
this:

[https://gist.github.com/anonymous/73ccac277baee8841470](https://gist.github.com/anonymous/73ccac277baee8841470)

Note that this now prints "Fake pass-by-value swap" like the Java version.

There is no way to write a Java version that prints "Real pass-by-reference
swap".

~~~
solipsism
Are you making the argument that C++ has pass-by-reference and Java does not?
No one disputes this. That's not my point. My point is whether the ability to
write a traditional "swap" is a good litmus test.

I've proved that you can write "swap" in Java. This behavior is in all
important ways equivalent to the basic, traditional C++ swap, even though Java
passes references by value and C++ passes by reference. You're arguing, "Yeah
but look, they look different! If you put the exact same comparison code
afterward, they return different things!" Well... yeah... that's because Java
and C++ are different! Apples and oranges. That has nothing to do with whether
the ability to write "swap" is a good litmus test.

The article says you cannot write "swap" in Java, therefore Java doesn't have
pass-by-reference. I'm saying "yes, you can write 'swap' in Java.. but still
Java doesn't have pass-by-reference.. so it's a bad litmus test." And you're
saying "Yeah but your swap looks different." And I'm saying "No shit, that's
because Java doesn't have pass-by-reference." The article didn't say the
litmus test is "can you write swap in a way that looks exactly like this C++
code?".

That's it for me, I'm bowing out!

~~~
jjnoakes
You can't write swap in Java as defined by the article - one that changes the
_values_ of the _parameters_. Your swap only follows the pointers and changes
the pointed-to objects.

A valid, real "swap" in Java is one that passes my example code and prints
"real pass-by-reference swap" and not "fake pass-by-value swap'.

------
diego898
I asked a question some time ago on SO [1] where Scott Stanchfield - "The Java
Dude" weighed in and it sparked quite a discussion. It is well worth reading
the discussion there as well as this one.

[1] [https://stackoverflow.com/questions/934775/changing-value-
af...](https://stackoverflow.com/questions/934775/changing-value-after-its-
placed-in-hashmap-changes-whats-inside-hashmap)

------
city41
I had a similar frustration over JavaScript recently and wrote a very similar
post: [http://www.mattgreer.org/articles/javascript-is-a-pass-by-
va...](http://www.mattgreer.org/articles/javascript-is-a-pass-by-value-
language/)

------
JBiserkov
A pointer in Java

    
    
        Dog d;
    

is exactly like C++'s

    
    
        Dog *d;
    

Following a pointer and calling a method

    
    
        d.setName("Fifi");
    

is exactly like C++'s

    
    
        d->setName("Fifi");

------
banachtarski
The C++ implementation of swap given is wrong.

SomeType temp = arg1;

This would do a deep copy of the object pointed to by the ref arg1. What is
intended is probably

SomeType& temp = arg1;

~~~
jjnoakes
No, the article was right.

You can't do a generic swap without 3 deep copies.

If you change temp to be a reference, then once you do "arg1 = arg2", you just
lost any way to get arg1's value back.

------
moru0011
if you want pass a reference to a reference do

Dog dog[] = { new Dog };

void method( Dog dog[] ) { dog[0] = new Dog(); }

Having this of side effect as a default would be an insane idea ofc., so I am
not sure what you are complaining about :-)

~~~
DonHopkins
No, that's passing by value a reference to an object (Dog array) that contains
a reference to another object (Dog). The variable "dog" that is the parameter
to "method" is passed by VALUE, not by reference. Passing something by
reference is NOT the same as passing a reference to something by value.

------
Timono
Java is Pass-By-Value for values and Pass-By-Copy-Reference for objects.

------
rspeer
Dear author: webhostinggeeks did not actually translate your article into
Serbo-Croatian for free. They just ran a shitty automatic translation and
added in links that boost their black hat SEO empire.

They target many people who host highly linked articles this way. They picked
Serbo-Croatian because you're unlikely to verify it.

Do not post translations unless you trust the translator (perhaps because you
paid them to do good work) or know the language.

------
miralabs
_In short: Java has pointers and is strictly pass-by-value._

It's a well know fact that Java has pointers given that you have
NullPointerException as an exception.

~~~
uiri
The confusion around whether or not Java has pointers comes from people
comparing it with C or C++. In Java, you can't dereference a pointer to an
Object and get some sort of Object value. Similarly, you can't perform an
"address of" operation on a primitive value and get a pointer to that value.
Similarly, you can't pass-by-reference (in the sense of the parent article) or
do pointer arithmetic in Java.

While Java technically has pointers (in the sense that it has pointer types),
it has dulled them so that you can't hurt yourself with them the same way that
C (and C++) permit.

------
anon4
You absolutely CAN write swap in Java:

    
    
        void <T> swap(T a, T b) {
            // use the Unsafe to copy a's memory to a temp buffer
            // then copy b's memory to a
            // then copy a's memory to b
            // Caution: Don't pass Integers or anything, okay
        }
    

Or, if the objects are Beans, just iterate the properties and swap them one by
one. In fact, if you know you're dealing with beans, the two don't even have
to be the same class, as long as their properties and types are the same.

~~~
shiro
No, it's not the same.

    
    
        X a = new X("foo");
        X b = new X("bar");
        X c = a;
        swap(a, b);
        // after this, a points to X("bar") and b points to
        // X("foo"), but c should remain pointing to X("foo"). 
    

If you swap the contents of the object, c would point to X("bar").

------
lucio
>Java is strictly pass-by-value, exactly as in C

In C you can pass a pointer, and a pointer to a pointer. I understand both
cases are usually called "pass-by-reference". If you call "pass-by-value" to
passing a pointer, then the notion of "pass-by-value" and "pass-by-reference"
are not very useful.

IMHO "pass-by-reference" means you can mutate the attributes of the thing
passed (as in java when you pass an object) and also means you can be
operating on a "volatile" area of memory, meaning another thread can CHANGE
the data while the function is executing.

OTOH "pass-by-value" means you get a "snapshot" of the value at the point of
the function-call, the copy is normally on the stack, and no other thread will
change the data while the function is running. Also you can mutate the area
with gusto without worrying of data-races, side-effects or altering the
calling function variables.

This two "definitions" of pass-by-value and pass-by-reference are the ones I
find useful regarding concurrency and side-effects.

If you tell me that passing an integer and passing an object are both the same
thing (pass-by-value) in Java, then I will tell you that pass-by-value and
pass-by-reference are not very useful concepts.

~~~
argonaut
It is a useful concept because there _are_ languages with pass-by-reference
constructs. C++, Swift (sort of, with inout parameters), are two examples that
come to mind. Java and C are simply not those languages.

~~~
cube00
You can pass double pointers in C so functions can change the original
pointer's address value. You can't do that in Java.

~~~
ta82828
Yes, you can do that in C, but that is still not pass by reference. In C you
are not passing the variable you are trying to change, you are passing a
_pointer to it_. You cannot write

    
    
      swap(a, b);
    

You have to write

    
    
      swap(&a, &b);

~~~
lucio
The problem is that you will label both cases as an example of "pass-by-
value", while they're fundamentally different.

That's why people call "pass-by-reference" the second example.

~~~
ta82828
They are both labelled pass-by-value because they are both pass-by-value. Yes,
they are different, but that doesn't mean one is pass-by-reference and the
other is pass-by-value.

The C example is equivalent to

    
    
      pa = &a;
      pb = &b;
      swap(pa, pb);
    

When _swap_ returns, the values of _pa_ and _pb_ are unchanged. Only the
values or _a_ and _b_ are changed. But _a_ and _b_ were not passed to swap.
Therefore this is not pass-by-reference, but rather passing a pointer to a
variable by value.

~~~
lucio
I fully understand the difference, and I know that you're technically correct.

What I'm saying is that people tend to abbreviate "pass-a-reference-by-value"
to "pass-by-reference" because the differences between passing a value (value
snapshot) and passing a reference-value (passing the address-of) are way more
important* than if the language syntax allows you to pass an "implicit"
variable reference or not. (the swap example)

*"more important" for code-reading, code-analysis, code-safety analysis, and also even more important in a concurrent environment because of side-effects and data-races.

Maybe the feature should be called "pass an implicit reference", which
describes better what Java does, instead of saying "everything is pass-by-
value" which is correct but, as the evidence shows (the mere existence of the
article), it is very confusing for "folks".

>I'm really tired of hearing folks (incorrectly) state "primitives are passed
by value, objects are passed by reference".

