
Java is Pass-by-Value - jxub
http://javadude.com/articles/passbyvalue.htm
======
lisper
This article is overly pedantic. Java's semantics are pass-by-value only of
you consider that the "values" that are being passed are pointers. But Java
doesn't have first-class pointers, it has implicit pointers. The only thing
you can do with a Java pointer "value" is to tacitly dereference it.

In fact, you can write a swap(x,y) function in Java. It goes something like
this:

    
    
        class foo { int value }
        
        void swap(foo x, foo y} {
          int temp = x.value;
          x.value = y.value;
          y.value = temp;
        }
    

(Yes, I know this isn't valid Java. Cut me a little slack here, OK?)

"But that's cheating" you protest. "That's not swapping the value of X and Y,
that's swapping the value of a slot in the values of X and Y, which happen to
be objects." Well, yeah. So? Compare that to this C code:

    
    
      struct foo { int value }
      
      void swap(struct foo x, struct foo y) {
        [same code as above]
      }
    

The effect of this function will be DIFFERENT. Specifically, the C function
will have no effect while the Java function will swap the value slots of X and
Y because C lets you pass a structure as a value while Java does not. All Java
"values" are (tacit) pointers to objects [1]. Pounding your fist on the table
and insisting that Java is pass-by-value because you can't write a swap(x,y)
function obscures this crucial difference.

[1] OK, it also has ints and floats of various sizes. But that's really it.

~~~
colanderman
But Java _isn 't_ pass-by-reference. Saying so is simply _wrong_ , for exactly
the reasons you write off as "pedantry". I see this play out all the time with
co-workers who are new to Python (which has the same semantics) being very
confused about why "numbers are passed by value but objects are passed by
reference".

Pedantry matters in our profession. Details have consequences.

~~~
lisper
> But Java isn't pass-by-reference

I didn't say it was. I said that insisting it is pass-by-value isn't helpful.

The real problem here is that we have only two terms which we're using to try
to distinguish between three different concepts.

~~~
tonysdg
Personally, I'd argue there's only one concept -- pass-by-value -- with a
whole lot of language-specific syntactic sugar as to _what_ is getting passed
by value. But I'll call myself out on that being even more pedantic than the
current discussion.

~~~
seanmcdirmid
That sounds like Robert Harper’s argument that all languages are statically
typed, it’s just that some languages only have one type.

~~~
twic
I've heard this term "unityped", but i'd always written it off as a
politically correct way of saying "untyped". Is there actually a worthwhile
argument for it?

Having thought about it for a minute or two, it seems pretty silly to me .
Types are all about restricting the set of values an expression can have, and
restricting the set of operations you can perform on an expression, such that
any operation you're allowed to perform on a value will always do something
sensible. Untyped languages don't do that, which makes them quite different
from typed languages. But then i've only thought about it for a minute or two.

I could imagine a genuinely unityped language. Perhaps one where every value
is a vector of real numbers with an infinite number of zeroes on the end, and
the operations are piecewise arithmetic, dot products, interleaving,
appending, etc. That would behave quite differently to the languages where you
get "undefined is not a function" and friends.

~~~
qznc
Untyped languages actually allow you to perform any operation on any value and
will always do something sensible. The sensible thing to do is to throw an
exception in most cases.

~~~
seanmcdirmid
The difference between safe dynamically typed and untyped is whether the throw
will happen or not. There are degrees of safety even in dynamically typed
languages.

~~~
coldtea
Where by "safe dynamically type" you probably mean "strongly typed" (as eg
Python).

------
Nokinside
These terms are so frustrating because they have "consistently wrong intuitive
semantics" (I don't know better term). They are like cognitive puns.

It's so easy to guess their meaning consistently wrong that people don't
brother to look them up. When several people wrongly guess the semantics wrong
exactly the same way and talk to each other, new meaning is established.

It's not uncommon to have office debate of the difference where 9 people are
sure that they know the right definition and the one person who argues for the
right definition can't convince them.

EDIT: there are already at least two comments that argue that the wrong
definition is the right definition. These guys feel so strongly that their
definition is right that nothing convinces them and people agree. It's a
hopeless pursuit to get this right.

[https://stackoverflow.com/questions/373419/whats-the-
differe...](https://stackoverflow.com/questions/373419/whats-the-difference-
between-passing-by-reference-vs-passing-by-value)

~~~
colanderman
> It's so easy to guess their meaning consistently wrong that people don't
> brother to look them up.

I find this to be the source of most programmers' confusion about most topics.
Sometimes I spend hours arguing trying to convince someone that X works one
way, because I've read the spec and the source code, while they believe that X
works a different way, because they looked at its name and used it that way
last time.

------
colanderman
I always just call this sort of thing "pass-by-pointer-value" to clear up any
confusion. To someone coming from C++, where objects are _actually_ passed by
value, saying that Java (or Python, or what-have-you) does the same is just
confusing.

~~~
chi3
Coming from C++, if "passing by pointer value" is considered "passing by
value", then what is the opposite? Not passing at all? I mean, there's always
going to be _some_ kind of value being passed?

~~~
lmm
If you write foo(&a), both "you pass a by reference" and "you pass &a by
value" are fair descriptions of what happens.

The confusion arises because Java doesn't explicitly distinguish between a and
&a; if you write "Foo a = new Foo();" in Java, the behaviour is similar to
"Foo *a = new Foo();" in C++. So if we ask how "a" is passed, is the "a" we're
talking about the reference or the value?

~~~
chi3
Ah, I see the reasoning. I only did basic Java in university so I might be
remembering incorrectly, but aren't variables storing non-primitive values
called "References"?

Seems weird to me to say that Java "passes by value" when all objects being
passed are actually references to objects.

~~~
lmm
> I only did basic Java in university so I might be remembering incorrectly,
> but aren't variables storing non-primitive values called "References"?

Technically yes, but since the language doesn't let you talk about references
directly, the concept rarely comes up. Like, in theory you could say "a is a
reference that refers to a value of type Foo", but people don't actually say
that; they just say "a is of type Foo".

> Seems weird to me to say that Java "passes by value" when all objects being
> passed are actually references to objects.

Indeed, completely agreed.

~~~
emidln
You do see this kind of language in Clojure, where you can talk about a var
separately from its value.

------
lucio
This is similar to relational algebra & relational databases.

In relational algebra a "relation" is what most people know as a "table".

"relation" is maybe a good name in the realm of relational algebra, but a bad
name in the realm of users of relational databases.

In this case "pass-by-value" and "pass-by-reference" are good names in the
realm of compiler theory ("I'm a compiler guy at heart") but very, very bad
names in the context of discussing parameter passing in java & objects.

~~~
danharaj
A relation can't have multiple identical rows, but a table in most databases
can, of course no primary key works for such a set of data and you can embed
such a table into another table which has an underlying relation.

Sorry, i agree with your point but I felt like being pedantic :3

------
xtrapolate
> "Pass-by-reference: The formal parameter merely acts as an alias for the
> actual parameter."

"Alias" means nothing to a CPU, nor is it an ABI. At the core, passing by
reference is _usually_ implemented by providing the "address-of" something to
a function (for example). The "address-of" itself, is passed by value. Going
by that logic, everything everywhere is passed by value.

~~~
chrisseaton
> "Alias" means nothing to a CPU, nor is it an ABI.

But the language isn't defined in terms of a CPU. It's defined in terms of
abstract semantic rules. You shouldn't think about implementation, especially
at the CPU level, when talking about semantics.

The idea is that the alias is implicit in pass-by-reference. It isn't implicit
in pass-by-value. How you implement that alias is irrelevant for discussion at
this level.

~~~
xtrapolate
> "But the language isn't defined in terms of a CPU."

I disagree. I submit the whole reason we pass objects by reference or by value
in the first place, has much more to do with conserving computational
resources/reducing runtime, than with providing abstract programming semantics
for software developers.

------
SigmundA
Having started off doing VB programming and now .Net and Javascript with some
C mixed in this all seems like second nature to me.

C# is somewhat more clear to me because it lets you do either, which VB kinda
did too.

The key point here is reference types vs value types, which is distinct from
pass by reference and pass by value.

Java is pass by value only with reference types and primitive value types.

C# has reference types and value types and pass by value default with pass by
reference optional.

passing a reference type by reference is passing a pointer to a pointer.

See: [https://docs.microsoft.com/en-
us/dotnet/csharp/programming-g...](https://docs.microsoft.com/en-
us/dotnet/csharp/programming-guide/classes-and-structs/passing-reference-type-
parameters)

------
quantumofmalice
This comes up once every few years. The confusion comes from the fact that
java syntactically hides the pointer for objects, which feel kind of like
structs.

It doesn't matter too much IMO. Most people intuitively understand how object
references work in modern programming languages, and these discussions don't
add a lot to their knowledge.

~~~
catamorphismic
I actually find it is a pretty big and universal pain point while people are
learning, particularly when switching languages.

------
colanderman
There's a lot of confusion in this thread about what "call-by-reference"
means. Let's be very clear. If Java were "call-by-reference", then this
function:

    
    
      static void foo(Object x) {
        x = null;
      }
    

would have an effect visible to the caller. This is exactly the case with C++
references, and C and Lisp macros, which _are_ call-by-reference. (C++, C,
Lisp, and the term "call-by-reference" all having existed _prior to Java_ , by
the way, so Java and its users do not get to redefine it.)

But the above function does _nothing_ in Java. Hence, Java is _not_ call-by-
reference.

Wikipedia has a nice quote [1] from Barbara Liskov (the namesake of the Liskov
substitution principle), made when she _invented_ the passing style used in
Java in _1974_ , for use in her language CLU:

"In particular it is not call by value because mutations of arguments
performed by the called routine will be visible to the caller. And it is not
call by reference because access is not given to the variables of the caller,
but merely to certain objects."

She settled on the term "call-by-sharing". Maybe we should all just agree on
that.

[1]
[https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sh...](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing)

------
skocznymroczny
I argue with my coworkers often about it. I think the problem is that what
Java calls references, works more like C/C++ pointer, rather than C++
reference. The name similarity but differing behaviour is what's confusing
people.

~~~
michaelcampbell
> I argue with my coworkers often about it.

I fail to see what possible value this has.

~~~
alangpierce
Pedantic arguments like this can be a good source of fun as long as everyone
approaches it in a lighthearted way and acknowledges that it's pedantic. I
could certainly see a conversation around pass-by-value/reference happening in
my office, but if it got to the point of people getting angry at each other,
that would be a sign that something is very wrong.

When actually communicating with people for the purpose of conveying ideas
(not just for fun), it's best to avoid terminology where not everyone has the
same understanding of the definition. Open discussions about terminology are
also a good way to identify these types of ambiguous terms and possibly come
up with technical terms that everyone agrees on.

------
dgreensp
I don’t see why C++ “references” should have a monopoly on the term
“reference," such that a language calling anything else a reference is making
an error. C++ references are actually kind of a weird/unusual language feature
that isn’t being taken up by other languages. I don’t see cause for reserving
a term for them. Each language can decide what it is going to call a
“reference.”

~~~
ohf
Java references are closer to C++ references than anything else. They're like
pointers until you access/call them, at which point they're just objects. C++
references are identical, but the syntax is a bit more explicit.

It _is_ a funny language feature to have when you think about it; it just so
happens to be useful. References and pointers are distinct in languages that
have both (C++), so not mixing the terms between languages is helpful. If Java
programmers started referring to their variables as "pointers," because
internally, that's more representative of what they are, I'd be a bit irked.

------
sorokod
There are two levels of misunderstanding to this discussion:

1\. The way parameters are actually passed in Java, primitives by value,
object references by value.

2\. How to call this mechanism.

My guess is that many fail on item 1. Once understanding of item 1 is
achieved, item 2 isn't terribly interesting.

------
radicalbyte
In C# you have an explicit syntax for passing a mutable pointer (i.e. a
pointer to the pointer) so it's harder for people to get confused.

------
stephengillie
"Create-copy" and "create-alias" are better ways to describe the concepts.
This post describes pass-by-value as create-copy, and pass-by-reference as
create-alias.

Create-copy - Copies the data into a new memory location, so modifying this
variable will not modify the original variable.

Create-alias - Creates a new name for the same memory location, so modifying
one variable will also modify the other variable.

Having spent too much time in Powershell, which defaults to create-copy, it
was jarring to switch to Javascript and the seemingly-non-deterministic
behavior of create-alias on setting a new variable equal to an array. From an
algebraic perspective, when I modify "foo", I expect "bar" to remain the same.

~~~
Zarel
The confusion comes up when you do a _shallow_ copy: Some modifications will
modify the original variable, and other modifications won't.

Pass-reference-by-value is just a special case of a shallow copy.

    
    
        let a = [1, 2, 3];
        let b = a;
        
        b[1] = 5; // will modify a
        b = [1, 6, 3]; // will not modify a
    

In languages like C++, there's a way to make it so that last line _would_
modify a, which is why there's a need to use different words for the different
phenomenon.

------
cup-of-tea
I thought this was common knowledge. I was taught that Java is pass-by-value
in compiler-writer terms, but as a programmer you can think of it as pass-by-
reference because you have no control over it.

~~~
Terr_
I believe the difficulty with "pass by reference" is that the phrase implies
(at least in other languages) that the function-body can potentially alter
variables _in the caller 's_ scope, by assigning something to the parameters
it is given.

In other words, "C-style" pass-by-reference means this function would have an
undesirable side-effect:

void foo(Thing x){ x = null; }

------
dep_b
I was looking for some kind of indicator when this article was written as the
topic and style of design could be from the 90’s and the copyright goes from
1996 to 2014

------
manaskarekar
Here is, what I thought, is an excellent video and the related article for
Python:

Ned Batchelder - Facts and Myths about Python names and values - PyCon 2015:
[https://www.youtube.com/watch?v=_AEJHKGk9ns](https://www.youtube.com/watch?v=_AEJHKGk9ns)

Article:
[https://nedbatchelder.com/text/names.html](https://nedbatchelder.com/text/names.html)

------
tunesmith
Is it bad to completely ignore this behavior? For instance, something like:

Dog d = new Dog("fido"); d = alterDog(d);

public Dog alterDog(Dog d) { d.name="arfybark"; return d; }

It's not quite a pure function since it changes it in place, but at least the
parameters and return types reflect the method. I ran across a term for this
practice in the past but don't remember what it's called.

~~~
ohf
I would actively avoid that, but only because it confuses me.

That syntax loosely implies that removing the second d assignment would allow
me to create new-but-altered dogs with alterDog(Dog), which isn't the case. If
I wanted to use assignments like that, I would try to go fully immutable with
factory methods that help me make slightly different, new dogs on the fly, and
return them.

------
ThoAppelsin
While C++ is a whole lot of different language with operator overloading amd
everything, I don't think the pass-by-reference in the C++'s way with &'s
before the variable/parameter identifiers is much different from how Java
handles the objects behind the curtains.

In Java with no explicit pointers available to its users, the way objects are
handled are explained better with the pass-by-reference concept than
(whooosh!, magic in) pointers (and out) passed-by-value reality. Pointer is a
foreign concept to Java, so it really makes more sense to its users that
object variables start referring to other objects when they are reassigned,
instead of the old object being changed in-place. Things get funky with
equality comparison via == operator, but still, it is better than pointers.

I also wonder, does C++ really pass-by-reference when parameters have &'s
behind their identifier declarations, or does it internally pass a reference
by value and dereference it every time it is used within that scope? Are 4/8
bytes allocated for the reference variable or not?

~~~
colanderman
No, it really is different. In C++ you can assign to variable references
without additional syntax. You cannot do this (at all) in Java.

I don't know what you mean by "really pass-by-reference". There is no such
concept of a "reference" at the CPU level; nor is that relevant to language
semantics. If you were to look at the generated assembly it would look
identical to as if pointer referencing and dereferencing were used.

~~~
ThoAppelsin
> I don't know what you mean by "really pass-by-reference".

I was wondering if `int &a2 = a;` allocates memory in stack to make `a2` refer
to `&a`, or does `a2` somehow truly become an alias for `a` in symbol table.
As you've said that the assembly would look the same as pointers being
dereferenced, then I suppose C++'s reference types are just a syntax sugar
around the C's way of achieving the pass-by-reference concept through passing
the address and then dereferencing it.

~~~
chi3
Unless I'm misunderstanding you, what you're asking is only possible in a
function signature if the compiler inlines it.

However, outside of function signatures, if you write:

int a = 2; int &aref = a; int b = aref;

I'd assume that the compiler is smart enough to optimize away &aref.

------
TazeTSchnitzel
This is a problem in PHP, which has both primitives (including copy-on-write
arrays) and Java-style objects, but it also has literal pass-by-reference
referencing (you can write a swap function). The misuse of “pass-by-reference”
here creates confusion.

------
emh68
It’s a VM language and therefore “pass by value” and “pass by reference” don’t
make sense in this context. But people love to subdivide everything into two
groups so have at it, who am I to rain on your party.

------
bullen
Just makes me think of how I learned to code this in C++ with array pointer by
reference and/or value (still don't know and really don't care ;)

int dosomething(int * & array) {}

That * & is just complete voodoo magic.

------
kstenerud
The fact that so many people get this wrong yet are so sure they're right is
indicative of a U/X issue. Fix the nomenclature and you'll fix the problem.

~~~
reikonomusha
Or it’s a reflection of a lack of rigorous training. Lots of folks like to
infer and consequently assume without reading.

~~~
gvx
That, and I don't think there is a real consensus on the nomenclature, even in
the literature. At least, I don't remember university lectures being at all
clear on the issue.

FWIW, I don't use pass-by-value or pass-by-reference to refer to languages
like Java, Python, Lua, etc... Instead, I use "pass-by-object-identity" (aka
"call-by-sharing", "call-by-object") to refer to the semantics of those
languages. It avoids the association many people have between the term "by-
value" and copying behaviour.

Also part of the problem: many beginning and intermediate programmers don't
understand the difference between rebinding and mutation. This leads to people
interpreting the following snippet:

    
    
      def foo(a, b):
          a = 2
          b.append(3)
      
      x = 1
      y = []
      foo(x, y)
      print(x, y) #1, [3]
    

... as meaning that ints are passed by value and lists by reference, while in
fact both are passed by object identity, and it is the fact that a is rebound
while b is mutated that made the difference.

------
slowmovintarget
Should probably be tagged [1996] as this article hits HN roughly once a year.
A good read, if one hasn't encountered it before.

------
crehn
TLDR: objects are not passed by reference; object references are passed by
value

~~~
itronitron
pro tip: objects are never passed, object references are :)

------
chris_wot
So in that last example, someDog after you have finished the function foo()
will be called Max... is this right?

~~~
itronitron
Yes, if you call the function like this, then Max will be the name of the dog
when the function returns...

Dog someDog = new Dog("Fifi");

foo(someDog);

System.out.println(someDog.getName()); // name will be Max

------
blattimwind
If something is pass-by-value, but the underlying value primitive is not
actually part of the language, we typically call this pass-by-object.

~~~
jjnoakes
Reference values are part of the Java language. It's the reason "==" doesn't
do what you'd expect it to, and why "a = ..." inside a method (assuming "a"
was a parameter) doesn't affect the caller.

