And who has the authority to decide?
Edit: Apparently I haven\'t succeeded in formulating my question well.
I am not asking how Java\'s
If you are familiar with C, perhaps the following analogy explains how Java works. This will be true only for objects of class-type (and not fundamental type).
In Java, we can have a variable and pass it to a function:
void f(Object x)
{
x.bar = 5; // #1j
x = new Foo; // #2j
}
void main()
{
Foo a;
a.bar = 4;
f(a);
// now a.bar == 5
}
In C, this would look as follows:
void f(struct Foo * p)
{
p->bar = 5; // #1c
p = malloc(sizeof(struct Foo)); // #2c
}
int main()
{
struct Foo * w = malloc(sizeof(struct Foo));
w->bar = 4;
f(w);
/* now w->bar = 5; */
}
In Java, variables of class-type are always references, which in C would be most faithfully mapped to pointers. But in function calls, the pointer itself is passed by copy. Accessing the pointer as in #1j and #1c modifies the original variable, so in that sense you are passing around a reference to the variable. However, the variable itself is only a pointer, and it itself is passed by copy. So when you assign something else to it. as in #2j and #2c, you are only rebinding the copy of the reference/pointer in the local scope of f
. The original variable, a
or w
in the respective examples, remains untouched.
In short: Everything is a reference, and references are passed by value.
In C, on the other hand, I could implement a true "passing by reference" by declaring void v(struct Foo ** r);
and calling f(&w)
; this would allow me to change w
itself from within f
.
Note 1: this is not true for fundamental types like int
, which are wholly passed by value.
Note 2: A C++ example would be a bit tidier since I could pass the pointer by reference (and I didn't have to say struct
): void f(Foo * & r) { r = new Foo; }
and f(w);
.
Both of your C examples actually demonstrate pass-by-value, because C doesn't have pass-by-reference. It's just that the value that you're passing is a pointer. Pass-by-reference occurs in languages such as Perl:
sub set_to_one($)
{
$_[0] = 1; # set argument = 1
}
my $a = 0;
set_to_one($a); # equivalent to: $a = 1
Here, the variable $a
is actually passed by reference, so the subroutine can modify it. It's not modifying some object that $a
is pointing to via indirection; rather, it modifies $a
itself.
Java is like C in this respect, except that in Java objects are "reference types", so all you ever have (and all you can ever pass) are pointers to them. Something like this:
void setToOne(Integer i)
{
i = 1; // set argument = 1
}
void foo()
{
Integer a = 0;
setToOne(a); // has no effect
}
won't actually change a
; it only reassigns i
.