Java pass by reference
Java always passes arguments by value NOT by reference.
Let me explain this through an example:
public class Main
{
public static void main(String[] args)
{
Foo f = new Foo("f");
changeReference(f); // It won't change the reference!
modifyReference(f); // It will modify the object that the reference variable "f" refers to!
}
public static void changeReference(Foo a)
{
Foo b = new Foo("b");
a = b;
}
public static void modifyReference(Foo c)
{
c.setAttribute("c");
}
}
I will explain this in steps:
Declaring a reference named
f
of typeFoo
and assign it to a new object of typeFoo
with an attribute"f"
.Foo f = new Foo("f");
From the method side, a reference of type
Foo
with a namea
is declared and it's initially assigned tonull
.public static void changeReference(Foo a)
As you call the method
changeReference
, the referencea
will be assigned to the object which is passed as an argument.changeReference(f);
Declaring a reference named
b
of typeFoo
and assign it to a new object of typeFoo
with an attribute"b"
.Foo b = new Foo("b");
a = b
is re-assigning the referencea
NOTf
to the object whose its attribute is"b"
.As you call
modifyReference(Foo c)
method, a referencec
is created and assigned to the object with attribute"f"
.c.setAttribute("c");
will change the attribute of the object that referencec
points to it, and it's same object that referencef
points to it.
I hope you understand now how passing objects as arguments works in Java :)
Is Java really passing objects by value?
Java always passes arguments by value, NOT by reference. In your example, you are still passing obj
by its value, not the reference itself. Inside your method changeName
, you are assigning another (local) reference, obj
, to the same object you passed it as an argument. Once you modify that reference, you are modifying the original reference, obj
, which is passed as an argument.
EDIT:
Let me explain this through an example:
public class Main
{
public static void main(String[] args)
{
Foo f = new Foo("f");
changeReference(f); // It won't change the reference!
modifyReference(f); // It will change the object that the reference refers to!
}
public static void changeReference(Foo a)
{
Foo b = new Foo("b");
a = b;
}
public static void modifyReference(Foo c)
{
c.setAttribute("c");
}
}
I will explain this in steps:
1- Declaring a reference named f
of type Foo
and assign it to a new object of type Foo
with an attribute "f"
.
Foo f = new Foo("f");
2- From the method side, a reference of type Foo
with a name a
is declared and it's initially assigned to null
.
public static void changeReference(Foo a)
3- As you call the method changeReference
, the reference a
will be assigned to the object which is passed as an argument.
changeReference(f);
4- Declaring a reference named b
of type Foo
and assign it to a new object of type Foo
with an attribute "b"
.
Foo b = new Foo("b");
5- a = b
is re-assigning the reference a
NOT f
to the object whose its attribute is "b"
.
6- As you call modifyReference(Foo c)
method, a reference c
is created and assigned to the object with attribute "f"
.
7- c.setAttribute("c");
will change the attribute of the object that reference c
points to it, and it's same object that reference f
points to it.
I hope you understand now how passing objects as arguments works in Java :)
Java is NEVER pass-by-reference, right?...right?
As Rytmis said, Java passes references by value. What this means is that you can legitimately call mutating methods on the parameters of a method, but you cannot reassign them and expect the value to propagate.
Example:
private void goodChangeDog(Dog dog) {
dog.setColor(Color.BLACK); // works as expected!
}
private void badChangeDog(Dog dog) {
dog = new StBernard(); // compiles, but has no effect outside the method
}
Edit: What this means in this case is that although voiceSetList
might change as a result of this method (it could have a new element added to it), the changes to vsName
will not be visible outside of the method. To prevent confusion, I often mark my method parameters final
, which keeps them from being reassigned (accidentally or not) inside the method. This would keep the second example from compiling at all.
java: pass-by-value or pass-by-reference
Java is always pass-by-value.
In the second case, though, you are passing a reference by-value (an array is an object, and Java objects are always accessed via references). Because the method now has a reference to the array, it is free to modify it.
Can I pass parameters by reference in Java?
Java is confusing because everything is passed by value. However for a parameter of reference type (i.e. not a parameter of primitive type) it is the reference itself which is passed by value, hence it appears to be pass-by-reference (and people often claim that it is). This is not the case, as shown by the following:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Will print Hello
to the console. The options if you wanted the above code to print Goodbye
are to use an explicit reference as follows:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Can we use pass by reference in java? If No How does java.util.Arrays.sort works?
Arrays are reference types, so the iArr
variable holds a reference to an array.
In other words, when you call
Arrays.sort(iArr);
you're passing a reference (by value) to the sort method, which sorts the array that iArr
refers to.
From comments:
What does passing a reference (by value) actually mean?
What pass by reference means is that you're basically passing the variable itself to the method. I.e., what ever the method does with the variable affects the variable on the outside. This is never the case in Java. (Try implementing a swap method and you'll see what I mean.) Passing by value means that you pass the value that's stored in the variable. In this case the value is a reference, so it's passing a reference by value.
Re. second update:
Judging from your image, I think you've understood the situation very well, and I think it boils down to terminology.
If we forget about C++ for a while, it's really simple. All you need to keep in mind is that (A) when you invoke method(var)
the argument is a copy of whatever var
contains, and (B) the content of a non-primitive variable is a reference (a "pointer" if you so like).
Note that in your question you have
int iArr[] = {2, 1, 9, 6, 4};
which is equivalent to
int[] iArr = new int[] { 2, 1, 9, 6, 4 };
so it all checks out: iArr
holds a reference and new
returns a reference.
When you invoke Arrays.sort(iArr)
the content of iArr
is passed (i.e. the reference to the array). This is still not pass-by-reference because the value is passed, not the variable itself. If you reassign the formal parameter inside the method to point to some other array, iArr
will still point to the original array when the method returns.
If we do think in terms of C++ things tend to be a bit more complicated; C++ notion of reference is slightly different. With a C++ reference you can in fact implement a real swap
:
void swap(int &x, int &y)
{
int temp = x;
x = y;
y = temp;
}
I.e. you can pass in "a variable" (as opposed to just the content of a variable). I like to think of this as you're sharing the scope of the variable with the method you're calling. This can't be done in Java.
So with that in mind, I'd say Java reference are much more like C++ pointers, except that they are limited in the sense that you can't dereference using *
operator as you can in C++ (you can't do *person
in Java, even though person
stores what corresponds to a pointer to a person) and you can't get the address of an object using &
operator. Also you can't do any pointer arithmetic. You can't for instance do iArr + 3
to get to the fourth element of your array.
Java Pass By Value and reference
You're incrementing x
twice, but on different dogs. Look at this code:
public static void foo(Dog d) {
++d.x;
d = new Dog("Taz");
++d.x;
}
Initially, d
refers to the dog with a name of Tom
, with x=100
. That isn't a copy of the original object - it's a reference to the same object. Java passes the reference by value, which isn't the same as either passing an object by value or passing an object by reference. It's important to understand that the value of aDog
in main
isn't a Dog
object - it's a reference to a Dog
object. The value of that reference is passed, by value, to your foo
method... so the initial value of d
is the same as the value of aDog
. Further changes to the d
variable itself (rather than the object its value refers to) do not change the aDog
variable.
So, looking at the rest of foo
:
- After the
++d.x
,d
refers to the dog with a name ofTom
, withx=101
. - After
d = new Dog("Taz")
,d
refers to a dog with a name ofTaz
, withx=100
. - After the
++d.x
,d
refers to the dog with a name ofTaz
, withx=101
.
The calling code only ever knows about the dog with a name of Tom
, so it prints out Tom 101.
Related Topics
How to Declare and Initialize an Array in Java
Stringbuilder VS String Concatenation in Tostring() in Java
Preparedstatement in Clause Alternatives
How to Best Position Swing Guis
Why Is Subtracting These Two Times (In 1927) Giving a Strange Result
Method Overloading For Null Argument
Why Is Java Vector (And Stack) Class Considered Obsolete or Deprecated
What Is the Volatile Keyword Useful For
Read/Write to Windows Registry Using Java
What Is the Reason Behind "Non-Static Method Cannot Be Referenced from a Static Context"
Manipulating an Access Database from Java Without Odbc
How to Generate a Random Alpha-Numeric String
Why Doesn't Java Allow Overriding of Static Methods
String Replace Method Is Not Replacing Characters
"Non-Static Method Cannot Be Referenced from a Static Context" Error