I always thought Java uses pass-by-reference.
However, I've seen a blog post that claims that Java uses pass-by-value.
I don't think I understand the distinction they're making.
What is the explanation?
I always thought Java uses pass-by-reference.
However, I've seen a blog post that claims that Java uses pass-by-value.
I don't think I understand the distinction they're making.
What is the explanation?
The terms "pass-by-value" and "pass-by-reference" have special, precisely defined meanings in computer science. These meanings differ from the intuition many people have when first hearing the terms. Much of the confusion in this discussion seems to come from this fact.
The terms "pass-by-value" and "pass-by-reference" are talking about variables. Pass-by-value means that the value of a variable is passed to a function/method. Pass-by-reference means that a reference to that variable is passed to the function. The latter gives the function a way to change the contents of the variable.
By those definitions, Java is always pass-by-value. Unfortunately, when we deal with variables holding objects we are really dealing with object-handles called references which are passed-by-value as well. This terminology and semantics easily confuse many beginners.
It goes like this:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true
aDog.getName().equals("Fifi"); // false
aDog == oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
In the example above aDog.getName() will still return "Max". The value aDog within main is not changed in the function foo with the Dog "Fifi" as the object reference is passed by value. If it were passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo.
Likewise:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
foo(aDog);
// when foo(...) returns, the name of the dog has been changed to "Fifi"
aDog.getName().equals("Fifi"); // true
// but it is still the same dog:
aDog == oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// this changes the name of d to be "Fifi"
d.setName("Fifi");
}
In the above example, Fifi is the dog's name after call to foo(aDog) because the object's name was set inside of foo(...). Any operations that foo performs on d are such that, for all practical purposes, they are performed on aDog, but it is not possible to change the value of the variable aDog itself.
For more information on pass by reference and pass by value, consult the following answer: https://stackoverflow.com/a/430958/6005228. This explains more thoroughly the semantics and history behind the two and also explains why Java and many other modern languages appear to do both in certain cases.
I just noticed you referenced my article.
The Java Spec says that everything in Java is pass-by-value. There is no such thing as "pass-by-reference" in Java.
The key to understanding this is that something like
Dog myDog;
is not a Dog; it's actually a pointer to a Dog. The use of the term "reference" in Java is very misleading and is what causes most of the confusion here. What they call "references" act/feel more like what we'd call "pointers" in most other languages.
What that means, is when you have
Dog myDog = new Dog("Rover");
foo(myDog);
you're essentially passing the address of the created Dog object to the foo method.
(I say essentially because Java pointers/references aren't direct addresses, but it's easiest to think of them that way.)
Suppose the Dog object resides at memory address 42. This means we pass 42 to the method.
if the Method were defined as
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
let's look at what's happening.
someDog is set to the value 42someDog is followed to the Dog it points to (the Dog object at address 42)Dog (the one at address 42) is asked to change his name to MaxDog is created. Let's say he's at address 74someDog to 74Dog it points to (the Dog object at address 74)Dog (the one at address 74) is asked to change his name to RowlfNow let's think about what happens outside the method:
Did myDog change?
There's the key.
Keeping in mind that myDog is a pointer, and not an actual Dog, the answer is NO. myDog still has the value 42; it's still pointing to the original Dog (but note that because of line "AAA", its name is now "Max" - still the same Dog; myDog's value has not changed.)
It's perfectly valid to follow an address and change what's at the end of it; that does not change the variable, however.
Java works exactly like C. You can assign a pointer, pass the pointer to a method, follow the pointer in the method and change the data that was pointed to. However, the caller will not see any changes you make to where that pointer points. (In a language with pass-by-reference semantics, the method function can change the pointer and the caller will see that change.)
In C++, Ada, Pascal and other languages that support pass-by-reference, you can actually change the variable that was passed.
If Java had pass-by-reference semantics, the foo method we defined above would have changed where myDog was pointing when it assigned someDog on line BBB.
Think of reference parameters as being aliases for the variable passed in. When that alias is assigned, so is the variable that was passed in.
A discussion in the comments warrants some clarification...
In C, you can write
void swap(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
int x = 1;
int y = 2;
swap(&x, &y);
This is not a special case in C. Both languages use pass-by-value semantics. Here the call site is creating additional data structure to assist the function to access and manipulate data.
The function is being passed pointers to data, and follows those pointers to access and modify that data.
A similar approach in Java, where the caller sets up assisting structure, might be:
void swap(int[] x, int[] y) {
int temp = x[0];
x[0] = y[0];
y[0] = temp;
}
int[] x = {1};
int[] y = {2};
swap(x, y);
(or if you wanted both examples to demonstrate features the other language doesn't have, create a mutable IntWrapper class to use in place of the arrays)
In these cases, both C and Java are simulating pass-by-reference. They're still both passing values (pointers to ints or arrays), and following those pointers inside the called function to manipulate the data.
Pass-by-reference is all about the function declaration/definition, and how it handles its parameters. Reference semantics apply to every call to that function, and the call site only needs to pass variables, no additional data structure.
These simulations require the call site and the function to cooperate. No doubt it's useful, but it's still pass-by-value.
Java is always pass by value, with no exceptions, ever.
So how is it that anyone can be at all confused by this, and believe that Java is pass by reference, or think they have an example of Java acting as pass by reference? The key point is that Java never provides direct access to the values of objects themselves, in any circumstances. The only access to objects is through a reference to that object. Because Java objects are always accessed through a reference, rather than directly, it is common to talk about fields and variables and method arguments as being objects, when pedantically they are only references to objects. The confusion stems from this (strictly speaking, incorrect) change in nomenclature.
So, when calling a method
int, long, etc.), the pass by value is the actual value of the primitive (for example, 3).So if you have doSomething(foo) and public void doSomething(Foo foo) { .. } the two Foos have copied references that point to the same objects.
Naturally, passing by value a reference to an object looks very much like (and is indistinguishable in practice from) passing an object by reference.
Java passes references by value.
So you can't change the reference that gets passed in.
Basically, reassigning Object parameters doesn't affect the argument, e.g.,
private static void foo(Object bar) {
bar = null;
}
public static void main(String[] args) {
String baz = "Hah!";
foo(baz);
System.out.println(baz);
}
will print out "Hah!" instead of null. The reason this works is because bar is a copy of the value of baz, which is just a reference to "Hah!". If it were the actual reference itself, then foo would have redefined baz to null.
Just to show the contrast, compare the following C++ and Java snippets:
In C++: Note: Bad code - memory leaks! But it demonstrates the point.
void cppMethod(int val, int &ref, Dog obj, Dog &objRef, Dog *objPtr, Dog *&objPtrRef)
{
val = 7; // Modifies the copy
ref = 7; // Modifies the original variable
obj.SetName("obj"); // Modifies the copy of Dog passed
objRef.SetName("objRef"); // Modifies the original Dog passed
objPtr->SetName("objPtr"); // Modifies the original Dog pointed to
// by the copy of the pointer passed.
objPtr = new Dog("newObjPtr"); // Modifies the copy of the pointer,
// leaving the original object alone.
objPtrRef->SetName("objRefPtr"); // Modifies the original Dog pointed to
// by the original pointer passed.
objPtrRef = new Dog("newObjPtrRef"); // Modifies the original pointer passed
}
int main()
{
int a = 0;
int b = 0;
Dog d0 = Dog("d0");
Dog d1 = Dog("d1");
Dog *d2 = new Dog("d2");
Dog *d3 = new Dog("d3");
cppMethod(a, b, d0, d1, d2, d3);
// a is still set to 0
// b is now set to 7
// d0 still have name "d0"
// d1 now has name "objRef"
// d2 now has name "objPtr"
// d3 now has name "newObjPtrRef"
}
In Java,
public static void javaMethod(int val, Dog objPtr)
{
val = 7; // Modifies the copy
objPtr.SetName("objPtr") // Modifies the original Dog pointed to
// by the copy of the pointer passed.
objPtr = new Dog("newObjPtr"); // Modifies the copy of the pointer,
// leaving the original object alone.
}
public static void main()
{
int a = 0;
Dog d0 = new Dog("d0");
javaMethod(a, d0);
// a is still set to 0
// d0 now has name "objPtr"
}
Java only has the two types of passing: by value for built-in types, and by value of the pointer for object types.
The crux of the matter is that the word reference in the expression "pass by reference" means something completely different from the usual meaning of the word reference in Java.
Usually in Java reference means a a reference to an object. But the technical terms pass by reference/value from programming language theory is talking about a reference to the memory cell holding the variable, which is something completely different.
In java everything is reference, so when you have something like:
Point pnt1 = new Point(0,0); Java does following:

Java doesn't pass method arguments by reference; it passes them by value. I will use example from this site:
public static void tricky(Point arg1, Point arg2) {
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args) {
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X1: " + pnt1.x + " Y1: " +pnt1.y);
System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X1: " + pnt1.x + " Y1:" + pnt1.y);
System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
}
Flow of the program:
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
Creating two different Point object with two different reference associated.

System.out.println("X1: " + pnt1.x + " Y1: " +pnt1.y);
System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
System.out.println(" ");
As expected output will be:
X1: 0 Y1: 0
X2: 0 Y2: 0
On this line 'pass-by-value' goes into the play...
tricky(pnt1,pnt2); public void tricky(Point arg1, Point arg2);
References pnt1 and pnt2 are passed by value to the tricky method, which means that now yours references pnt1 and pnt2 have their copies named arg1 and arg2.So pnt1 and arg1 points to the same object. (Same for the pnt2 and arg2)

In the tricky method:
arg1.x = 100;
arg1.y = 100;

Next in the tricky method
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
Here, you first create new temp Point reference which will point on same place like arg1 reference. Then you move reference arg1 to point to the same place like arg2 reference.
Finally arg2 will point to the same place like temp.

From here scope of tricky method is gone and you don't have access any more to the references: arg1, arg2, temp. But important note is that everything you do with these references when they are 'in life' will permanently affect object on which they are point to.
So after executing method tricky, when you return to main, you have this situation:

So now, completely execution of program will be:
X1: 0 Y1: 0
X2: 0 Y2: 0
X1: 100 Y1: 100
X2: 0 Y2: 0
There are already great answers that cover this. I wanted to make a small contribution by sharing a very simple example (which will compile) contrasting the behaviors between Pass-by-reference in c++ and Pass-by-value in Java.
A few points:
C++ pass by reference example:
using namespace std;
#include <iostream>
void change (char *&str){ // the '&' makes this a reference parameter
str = NULL;
}
int main()
{
char *str = "not Null";
change(str);
cout<<"str is " << str; // ==>str is <null>
}
Java pass "a Java reference" by value example
public class ValueDemo{
public void change (String str){
str = null;
}
public static void main(String []args){
ValueDemo vd = new ValueDemo();
String str = "not null";
vd.change(str);
System.out.println("str is " + str); // ==> str is not null!!
// Note that if "str" was
// passed-by-reference, it
// WOULD BE NULL after the
// call to change().
}
}
EDIT
Several people have written comments which seem to indicate that either they are not looking at my examples or they don't get the c++ example. Not sure where the disconnect is, but guessing the c++ example is not clear. I'm posting the same example in pascal because I think pass-by-reference looks cleaner in pascal, but I could be wrong. I might just be confusing people more; I hope not.
In pascal, parameters passed-by-reference are called "var parameters". In the procedure setToNil below, please note the keyword 'var' which precedes the parameter 'ptr'. When a pointer is passed to this procedure, it will be passed by reference. Note the behavior: when this procedure sets ptr to nil (that's pascal speak for NULL), it will set the argument to nil--you can't do that in Java.
program passByRefDemo;
type
iptr = ^integer;
var
ptr: iptr;
procedure setToNil(var ptr : iptr);
begin
ptr := nil;
end;
begin
new(ptr);
ptr^ := 10;
setToNil(ptr);
if (ptr = nil) then
writeln('ptr seems to be nil'); { ptr should be nil, so this line will run. }
end.
EDIT 2
Some excerpts from "THE Java Programming Language" by Ken Arnold, James Gosling (the guy who invented Java), and David Holmes, chapter 2, section 2.6.5
All parameters to methods are passed "by value". In other words, values of parameter variables in a method are copies of the invoker specified as arguments.
He goes on to make the same point regarding objects . . .
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".
And towards the end of the same section he makes a broader statement about java being only pass by value and never pass by reference.
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.
This section of the book has a great explanation of parameter passing in Java and of the distinction between pass-by-reference and pass-by-value and it's by the creator of Java. I would encourage anyone to read it, especially if you're still not convinced.
I think the difference between the two models is very subtle and unless you've done programming where you actually used pass-by-reference, it's easy to miss where two models differ.
I hope this settles the debate, but probably won't.
EDIT 3
I might be a little obsessed with this post. Probably because I feel that the makers of Java inadvertently spread misinformation. If instead of using the word "reference" for pointers they had used something else, say dingleberry, there would've been no problem. You could say, "Java passes dingleberries by value and not by reference", and nobody would be confused.
That's the reason only Java developers have issue with this. They look at the word "reference" and think they know exactly what that means, so they don't even bother to consider the opposing argument.
Anyway, I noticed a comment in an older post, which made a balloon analogy which I really liked. So much so that I decided to glue together some clip-art to make a set of cartoons to illustrate the point.
Passing a reference by value--Changes to the reference are not reflected in the caller's scope, but the changes to the object are. This is because the reference is copied, but the both the original and the copy refer to the same object.

Pass by reference--There is no copy of the reference. Single reference is shared by both the caller and the function being called. Any changes to the reference or the Object's data are reflected in the caller's scope.

EDIT 4
I have seen posts on this topic which describe the low level implementation of parameter passing in Java, which I think is great and very helpful because it makes an abstract idea concrete. However, to me the question is more about the behavior described in the language specification than about the technical implementation of the behavior. This is an exerpt from the Java Language Specification, section 8.4.1 :
When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor. The Identifier that appears in the DeclaratorId may be used as a simple name in the body of the method or constructor to refer to the formal parameter.
Which means, java creates a copy of the passed parameters before executing a method. Like most people who studied compilers in college, I used "The Dragon Book" which is THE compilers book. It has a good description of "Call-by-value" and "Call-by-Reference" in Chapter 1. The Call-by-value description matches up with Java Specs exactly.
Back when I studied compilers-in the 90's, I used the first edition of the book from 1986 which pre-dated Java by about 9 or 10 years. However, I just ran across a copy of the 2nd Eddition from 2007 which actually mentions Java! Section 1.6.6 labeled "Parameter Passing Mechanisms" describes parameter passing pretty nicely. Here is an excerpt under the heading "Call-by-value" which mentions Java:
In call-by-value, the actual parameter is evaluated (if it is an expression) or copied (if it is a variable). The value is placed in the location belonging to the corresponding formal parameter of the called procedure. This method is used in C and Java, and is a common option in C++ , as well as in most other languages.
As far as I know, Java only knows call by value. This means for primitive datatypes you will work with an copy and for objects you will work with an copy of the reference to the objects. However I think there are some pitfalls; for example, this will not work:
public static void swap(StringBuffer s1, StringBuffer s2) {
StringBuffer temp = s1;
s1 = s2;
s2 = temp;
}
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer("Hello");
StringBuffer s2 = new StringBuffer("World");
swap(s1, s2);
System.out.println(s1);
System.out.println(s2);
}
This will populate Hello World and not World Hello because in the swap function you use copys which have no impact on the references in the main. But if your objects are not immutable you can change it for example:
public static void appendWorld(StringBuffer s1) {
s1.append(" World");
}
public static void main(String[] args) {
StringBuffer s = new StringBuffer("Hello");
appendWorld(s);
System.out.println(s);
}
This will populate Hello World on the command line. If you change StringBuffer into String it will produce just Hello because String is immutable. For example:
public static void appendWorld(String s){
s = s+" World";
}
public static void main(String[] args) {
String s = new String("Hello");
appendWorld(s);
System.out.println(s);
}
However you could make a wrapper for String like this which would make it able to use it with Strings:
class StringWrapper {
public String value;
public StringWrapper(String value) {
this.value = value;
}
}
public static void appendWorld(StringWrapper s){
s.value = s.value +" World";
}
public static void main(String[] args) {
StringWrapper s = new StringWrapper("Hello");
appendWorld(s);
System.out.println(s.value);
}
edit: i believe this is also the reason to use StringBuffer when it comes to "adding" two Strings because you can modifie the original object which u can't with immutable objects like String is.
You can never pass by reference in Java, and one of the ways that is obvious is when you want to return more than one value from a method call. Consider the following bit of code in C++:
void getValues(int& arg1, int& arg2) {
arg1 = 1;
arg2 = 2;
}
void caller() {
int x;
int y;
getValues(x, y);
cout << "Result: " << x << " " << y << endl;
}
Sometimes you want to use the same pattern in Java, but you can't; at least not directly. Instead you could do something like this:
void getValues(int[] arg1, int[] arg2) {
arg1[0] = 1;
arg2[0] = 2;
}
void caller() {
int[] x = new int[1];
int[] y = new int[1];
getValues(x, y);
System.out.println("Result: " + x[0] + " " + y[0]);
}
As was explained in previous answers, in Java you're passing a pointer to the array as a value into getValues. That is enough, because the method then modifies the array element, and by convention you're expecting element 0 to contain the return value. Obviously you can do this in other ways, such as structuring your code so this isn't necessary, or constructing a class that can contain the return value or allow it to be set. But the simple pattern available to you in C++ above is not available in Java.
The distinction, or perhaps just the way I remember as I used to be under the same impression as the original poster is this: Java is always pass by value. All objects( in Java, anything except for primitives) in Java are references. These references are passed by value.
As many people mentioned it before, Java is always pass-by-value
Here is another example that will help you understand the difference (the classic swap example):
public class Test {
public static void main(String[] args) {
Integer a = new Integer(2);
Integer b = new Integer(3);
System.out.println("Before: a = " + a + ", b = " + b);
swap(a,b);
System.out.println("After: a = " + a + ", b = " + b);
}
public static swap(Integer iA, Integer iB) {
Integer tmp = iA;
iA = iB;
iB = tmp;
}
}
Prints:
Before: a = 2, b = 3
After: a = 2, b = 3
This happens because iA and iB are new local reference variables that have the same value of the passed references (they point to a and b respectively). So, trying to change the references of iA or iB will only change in the local scope and not outside of this method.
I always think of it as "pass by copy". It is a copy of the value be it primitive or reference. If it is a primitive it is a copy of the bits that are the value and if it is an Object it is a copy of the reference.
public class PassByCopy{
public static void changeName(Dog d){
d.name = "Fido";
}
public static void main(String[] args){
Dog d = new Dog("Maxx");
System.out.println("name= "+ d.name);
changeName(d);
System.out.println("name= "+ d.name);
}
}
class Dog{
public String name;
public Dog(String s){
this.name = s;
}
}
output of java PassByCopy:
name= Maxx
name= Fido
Primitive wrapper classes and Strings are immutable so any example using those types will not work the same as other types/objects.
To make a long story short, Java objects have some very peculiar properties.
In general, Java has primitive types (int, bool, char, double, etc) that are passed directly by value. Then Java has objects (everything that derives from java.lang.Object). Objects are actually always handled through a reference (a reference being a pointer that you can't touch). That means that in effect, objects are passed by reference, as the references are normally not interesting. It does however mean that you cannot change which object is pointed to as the reference itself is passed by value.
Does this sound strange and confusing? Let's consider how C implements pass by reference and pass by value. In C, the default convention is pass by value. void foo(int x) passes an int by value. void foo(int *x) is a function that does not want an int a, but a pointer to an int: foo(&a). One would use this with the & operator to pass a variable address.
Take this to C++, and we have references. References are basically (in this context) syntactic sugar that hide the pointer part of the equation: void foo(int &x) is called by foo(a), where the compiler itself knows that it is a reference and the address of the non-reference a should be passed. In Java, all variables referring to objects are actually of reference type, in effect forcing call by reference for most intends and purposes without the fine grained control (and complexity) afforded by, for example, C++.
I have created a thread devoted to these kind of questions for any programming languages here.
Java is also mentioned. Here is the short summary:
A few corrections to some posts.
C does NOT support pass by reference. It is ALWAYS pass by value. C++ does support pass by reference, but is not the default and is quite dangerous.
It doesn't matter what the value is in Java: primitive or address(roughly) of object, it is ALWAYS passed by value.
If a Java object "behaves" like it is being passed by reference, that is a property of mutability and has absolutely nothing to do with passing mechanisms.
I am not sure why this is so confusing, perhaps because so many Java "programmers" are not formally trained, and thus do not understand what is really going on in memory?
This is the best way to answer the question imo...
First, we must understand that, in Java, the parameter passing behavior...
public void foo(Object param)
{
// some code in foo...
}
public void bar()
{
Object obj = new Object();
foo(obj);
}
is exactly the same as...
public void bar()
{
Object obj = new Object();
Object param = obj;
// some code in foo...
}
not considering stack locations, which aren't relevant in this discussion.
So, in fact, what we're looking for in Java is how variable assignment works. I found it in the docs :
One of the most common operators that you'll encounter is the simple assignment operator "=" [...] it assigns the value on its right to the operand on its left:
int cadence = 0;
int speed = 0;
int gear = 1;This operator can also be used on objects to assign object references [...]
It's clear how this operator acts in two distinct ways: assign values and assign references. The last, when it's an object... the first, when it isn't an object, that is, when it's a primitive. But so, can we understand that Java's function params can be pass-by-value and pass-by-reference?
The truth is in the code. Let's try it:
public class AssignmentEvaluation
{
static public class MyInteger
{
public int value = 0;
}
static public void main(String[] args)
{
System.out.println("Assignment operator evaluation using two MyInteger objects named height and width\n");
MyInteger height = new MyInteger();
MyInteger width = new MyInteger();
System.out.println("[1] Assign distinct integers to height and width values");
height.value = 9;
width.value = 1;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things! \n");
System.out.println("[2] Assign to height's value the width's value");
height.value = width.value;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");
System.out.println("[3] Assign to height's value an integer other than width's value");
height.value = 9;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things yet! \n");
System.out.println("[4] Assign to height the width object");
height = width;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");
System.out.println("[5] Assign to height's value an integer other than width's value");
height.value = 9;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are the same thing now! \n");
System.out.println("[6] Assign to height a new MyInteger and an integer other than width's value");
height = new MyInteger();
height.value = 1;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things again! \n");
}
}
This is the output of my run:
Assignment operator evaluation using two MyInteger objects named height and width [1] Assign distinct integers to height and width values -> height is 9 and width is 1, we are different things! [2] Assign to height's value the width's value -> height is 1 and width is 1, are we the same thing now? [3] Assign to height's value an integer other than width's value -> height is 9 and width is 1, we are different things yet! [4] Assign to height the width object -> height is 1 and width is 1, are we the same thing now? [5] Assign to height's value an integer other than width's value -> height is 9 and width is 9, we are the same thing now! [6] Assign to height a new MyInteger and an integer other than width's value -> height is 1 and width is 9, we are different things again!
In [2] we have distinct objects and assign one variable's value to the other. But after assigning a new value in [3] the objects had different values, which means that in [2] the assigned value was a copy of the primitive variable, usually called pass-by-value, otherwise, the values printed in [3] should be the same.
In [4] we still have distinct objects and assign one object to the other. And after assigning a new value in [5] the objects had the same values, which means that in [4] the assigned object was not a copy of the other, which should be called pass-by-reference. But, if we look carefully in [6], we can't be so sure that no copy was done... ?????
We can't be so sure because in [6] the objects were the same, then we assigned a new object to one of them, and after, the objects had different values! How can they be distinct now if they were the same? They should be the same here too! ?????
We'll need to remember the docs to understand what's going on:
This operator can also be used on objects to assign object references
So our two variables were storing references... our variables had the same reference after [4] and different references after [6]... if such a thing is possible, this means that assignment of objects is done by copy of the object's reference, otherwise, if it was not a copy of reference, the printed value of the variables in [6] should be the same. So objects (references), just like primitives, are copied to variables through assignment, what people usually call pass-by-value. That's the only pass-by- in Java.
Java copies the reference by value. So if you change it to something else (e.g, using new) the reference does not change outside the method. For native types, it is always pass by value.
When I say pass by value it means whenever caller has invoked the callee the arguments(ie: the data to be passed to the other function) is copied and placed in the formal parameters (callee's local variables for receiving the input). Java makes data communications from one function to other function only in a pass by value environment.
An important point would be to know that even C language is strictly passed by value only:
ie: Data is copied from caller to the callee and more ever the operation performed by the callee are on the same memory location and
what we pass them is the address of that location that we obtain from (&) operator and the identifier used in the formal parameters are declared to be a pointer variable (*) using which we can get inside the memory location for accessing the data in it.
Hence here the formal parameter is nothing but mere aliases for that location. And any modifications done on that location is visible where ever that scope of the variable (that identifies that location) is alive.
In Java, there is no concept of pointers (ie: there is nothing called a pointer variable), although we can think of reference variable as a pointer technically in java we call it as a handle. The reason why we call the pointer to an address as a handle in java is because a pointer variable is capable of performing not just single dereferencing but multiple dereferencing
for example: int *p; in P means p points to an integer
and int **p; in C means p is pointer to a pointer to an integer
we dont have this facility in Java, so its absolutely correct and technically legitimate to say it as an handle, also there are rules for pointer arithmetic in C. Which allows performing arithmetic operation on pointers with constraints on it.
In C we call such mechanism of passing address and receiving them with pointer variables as pass by reference since we are passing their addresses and receiving them as pointer variable in formal parameter but at the compiler level that address is copied into pointer variable (since data here is address even then its data ) hence we can be 100% sure that C is Strictly passed by value (as we are passing data only)
(and if we pass the data directly in C we call that as pass by value.)
In java when we do the same we do it with the handles; since they are not called pointer variables like in (as discussed above) even though we are passing the references we cannot say its pass by reference since we are not collecting that with a pointer variable in Java.
Hence Java strictly use pass by value mechanism
I see that all answers contain the same: pass by value. However, a recent Brian Goetz update on project Valhalla actually answers it differently:
Indeed, it is a common “gotcha” question about whether Java objects are passed by value or by reference, and the answer is “neither”: object references are passed by value.
You can read more here: State of Valhalla. Section 2: Language Model
Edit: Brian Goetz is Java Language Architect, leading such projects as Project Valhalla and Project Amber.
Edit-2020-12-08: Updated State of Valhalla
Long story short:
The End.
(2) is too easy. Now if you want to think of what (1) implies, imagine you have a class Apple:
class Apple {
private double weight;
public Apple(double weight) {
this.weight = weight;
}
// getters and setters ...
}
then when you pass an instance of this class to the main method:
class Main {
public static void main(String[] args) {
Apple apple = new Apple(3.14);
transmogrify(apple);
System.out.println(apple.getWeight()+ " the goose drank wine...";
}
private static void transmogrify(Apple apple) {
// does something with apple ...
apple.setWeight(apple.getWeight()+0.55);
}
}
oh.. but you probably know that, you're interested in what happens when you do something like this:
class Main {
public static void main(String[] args) {
Apple apple = new Apple(3.14);
transmogrify(apple);
System.out.println("Who ate my: "+apple.getWeight()); // will it still be 3.14?
}
private static void transmogrify(Apple apple) {
// assign a new apple to the reference passed...
apple = new Apple(2.71);
}
}
Now, people like to bicker endlessly about whether "pass by reference" is the correct way to describe what Java et al. actually do. The point is this:
In my book that's called passing by reference.
— Brian Bi - Which programming languages are pass by reference?
A simple test to check whether a language supports pass-by-reference is simply writing a traditional swap. Can you write a traditional swap(a,b) method/function in Java?
A traditional swap method or function takes two arguments and swaps them such that variables passed into the function are changed outside the function. Its basic structure looks like
(Non-Java) Basic swap function structure
swap(Type arg1, Type arg2) {
Type temp = arg1;
arg1 = arg2;
arg2 = temp;
}
If you can write such a method/function in your language such that calling
Type var1 = ...;
Type var2 = ...;
swap(var1,var2);
actually switches the values of the variables var1 and var2, the language supports pass-by-reference. But Java does not allow such a thing as it supports passing the values only and not pointers or references.
Not to repeat, but one point to those who might still be confused after reading many answers:
pass by value in Java is NOT EQUAL to pass by value in C++, though it sounds like that, which is probably why there's confusionBreaking it down:
pass by value in C++ means passing the value of the object (if object), literarily the copy of the objectpass by value in Java means passing the address value of the object (if object), not really the "value" (a copy) of the object like C++pass by value in Java, operating on an object (e.g. myObj.setName("new")) inside a function has effects on the object outside the function; by pass by value in C++, it has NO effects on the one outside.pass by reference in C++, operating on an object in a function DOES have effects on the one outside! Similar (just similar, not the same) to pass by value in Java, no?.. and people always repeat "there's no pass by reference in Java", => BOOM, confusion starts...So, friends, all is just about the difference of terminology definition (across languages), you just need to know how it works and that's it (though sometimes a bit confusing how it's called I admit)!
It's a bit hard to understand, but Java always copies the value - the point is, normally the value is a reference. Therefore you end up with the same object without thinking about it...
Java is only passed by value. there is no pass by reference, for example, you can see the following example.
package com.asok.cop.example.task;
public class Example {
int data = 50;
void change(int data) {
data = data + 100;// changes will be in the local variable
System.out.println("after add " + data);
}
public static void main(String args[]) {
Example op = new Example();
System.out.println("before change " + op.data);
op.change(500);
System.out.println("after change " + op.data);
}
}
Output:
before change 50
after add 600
after change 50
as Michael says in the comments:
objects are still passed by value even though operations on them behave like pass-by-reference. Consider
void changePerson(Person person){ person = new Person(); }the callers reference to the person object will remain unchanged. Objects themselves are passed by value but their members can be affected by changes. To be true pass-by-reference, we would have to be able to reassign the argument to a new object and have the change be reflected in the caller.
A: Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
Take the badSwap() method for example:
public void badSwap(int var1, int var2)
{
int temp = var1;
var1 = var2;
var2 = temp;
}
When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object, since Java passes object references by value as well. Now, here is where it gets tricky:
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
If we execute this main() method, we see the following output:
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In the main() method, pnt1 and pnt2 are nothing more than object references. When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.

Figure 1. After being passed to a method, an object will have at least two references
Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail.The method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references. For a swap to succeed outside of the method call, we need to swap the original references, not the copies.
Java is always pass by value, not pass by reference
First of all, we need to understand what pass by value and pass by reference are.
Pass by value means that you are making a copy in memory of the actual parameter's value that is passed in. This is a copy of the contents of the actual parameter.
Pass by reference (also called pass by address) means that a copy of the address of the actual parameter is stored.
Sometimes Java can give the illusion of pass by reference. Let's see how it works by using the example below:
public class PassByValue {
public static void main(String[] args) {
Test t = new Test();
t.name = "initialvalue";
new PassByValue().changeValue(t);
System.out.println(t.name);
}
public void changeValue(Test f) {
f.name = "changevalue";
}
}
class Test {
String name;
}
The output of this program is:
changevalue
Let's understand step by step:
Test t = new Test(); As we all know it will create an object in the heap and return the reference value back to t. For example, suppose the value of t is 0x100234 (we don't know the actual JVM internal value, this is just an example) .
first illustration
new PassByValue().changeValue(t);
When passing reference t to the function it will not directly pass the actual reference value of object test, but it will create a copy of t and then pass it to the function. Since it is passing by value, it passes a copy of the variable rather than the actual reference of it. Since we said the value of t was 0x100234, both t and f will have the same value and hence they will point to the same object.
second illustration
If you change anything in the function using reference f it will modify the existing contents of the object. That is why we got the output changevalue, which is updated in the function.
To understand this more clearly, consider the following example:
public class PassByValue {
public static void main(String[] args) {
Test t = new Test();
t.name = "initialvalue";
new PassByValue().changeRefence(t);
System.out.println(t.name);
}
public void changeRefence(Test f) {
f = null;
}
}
class Test {
String name;
}
Will this throw a NullPointerException? No, because it only passes a copy of the reference. In the case of passing by reference, it could have thrown a NullPointerException, as seen below:
third illustration
Hopefully this will help.
Java always passes parameters by value.
All object references in Java are passed by value. This means that a copy of the value will be passed to a method. But the trick is that passing a copy of the value also changes the real value of the object.
Please refer to the below example,
public class ObjectReferenceExample {
public static void main(String... doYourBest) {
Student student = new Student();
transformIntoHomer(student);
System.out.println(student.name);
}
static void transformIntoDuleepa(Student student) {
student.name = "Duleepa";
}
}
class Student {
String name;
}
In this case, it will be Duleepa!
The reason is that Java object variables are simply references that point to real objects in the memory heap.
Therefore, even though Java passes parameters to methods by value, if the variable points to an object reference, the real object will also be changed.
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
Take the badSwap() method for example:
public void badSwap(int var1, int
var2{ int temp = var1; var1 = var2; var2 =
temp; }
When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object, since Java passes object references by value as well. Now, here is where it gets tricky:
public void tricky(Point arg1, Point arg2)
{ arg1.x = 100; arg1.y = 100; Point temp = arg1; arg1 = arg2; arg2 = temp; }
public static void main(String [] args) {
Point pnt1 = new Point(0,0); Point pnt2
= new Point(0,0); System.out.println("X:
" + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y:
" +pnt2.y); System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y); }
If we execute this main() method, we see the following output:
X: 0 Y: 0 X: 0 Y: 0 X: 100 Y: 100 X: 0 Y: 0
The method successfully alters the value ofpnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In themain() method, pnt1 and pnt2 are nothing more than object references. When you passpnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.
Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail. As Figure 2 illustrates, the method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references. For a swap to succeed outside of the method call, we need to swap the original references, not the copies.
Java passes references to objects by value.
So if any modification is done to the Object to which the reference argument points it will be reflected back on the original object.
But if the reference argument point to another Object still the original reference will point to original Object.
First let's understand Memory allocation in Java: Stack and Heap are part of Memory that JVM allocates for different purposes. The stack memory is pre-allocated to thread, when it is created, therefore, a thread cannot access the Stack of other thread. But Heap is available to all threads in a program.
For a thread, Stack stores all local data, metadata of program, primitive type data and object reference. And, Heap is responsible for storage of actual object.
Book book = new Book("Effective Java");
In the above example, the reference variable is "book" which is stored in stack. The instance created by new operator -> new Book("Effective Java") is stored in Heap. The ref variable "book" has address of the object allocated in Heap. Let's say the address is 1001.
Consider passing a primitive data type i.e. int, float, double etc.
public class PrimitiveTypeExample {
public static void main(string[] args) {
int num = 10;
System.out.println("Value before calling method: " + num);
printNum(num);
System.out.println("Value after calling method: " + num);
}
public static void printNum(int num){
num = num + 10;
System.out.println("Value inside printNum method: " + num);
}
}
Output is: Value before calling method: 10 Value inside printNum method: 20 Value after calling method: 10
int num =10; -> this allocates the memory for "int" in Stack of the running thread, because, it is a primitive type. Now when printNum(..) is called, a private stack is created within the same thread. When "num" is passed to this method, a copy of "num" is created in the method stack frame. num = num+10; -> this adds 10 and modifies the the int variable within the method stack frame. Therefore, the original num outside the method stack frame remains unchanged.
Consider, the example of passing the object of a custom class as an argument.
In the above example, ref variable "book" resides in stack of thread executing the program, and the object of class Book is created in Heap space when program executes new Book(). This memory location in Heap is referred by "book". When "book" is passed as method argument, a copy of "book" is created in private stack frame of method within the same stack of thread. Therefore, the copied reference variable points to the same object of class "Book" in the Heap.
The reference variable within method stack frame sets a new value to same object. Therefore, it is reflected when original ref variable "book" gets its value. Note that in case of passing reference variable, if it is initialized again in called method, it then points to new memory location and any operation does not affect the previous object in the Heap.
Therefore, when anything is passed as method argument, it is always the Stack entity - either primitive or reference variable. We never pass something that is stored in Heap. Hence, in Java, we always pass the value in the stack, and it is pass by value.
For simplicity and verbosity
Its pass reference by value:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true
aDog.getName().equals("Fifi"); // false
aDog == oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
I'd say it in another way:
In java references are passed (but not objects) and these references are passed-by-value (the reference itself is copied and you have 2 references as a result and you have no control under the 1st reference in the method).
Just saying: pass-by-value might be not clear enough for beginners. For instance in Python the same situation but there are articles, which describe that they call it pass-by-reference, only cause references are used.
Here a more precise definition:
So in C/C++ you can create a function that swaps two values passed using the references:
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
You can see it has a unique reference to a and b, so we do not have a copy, tmp just hold unique references.
The same function in java does not have side effects, the parameter passing is just like the code above without references.
Although java work with pointers/references, the parameters are not unique pointers, in each attribution, they are copied instead just assigned like C/C++
Java passes parameters by value, There is no option of passing a reference in Java.
But at the complier binding level layer, It uses reference internally not exposed to the user.
It is essential as it saves a lot of memory and improves speed.
public class Test {
static class Dog {
String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Dog other = (Dog) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public String getName() {
return name;
}
public void setName(String nb) {
this.name = nb;
}
Dog(String sd) {
this.name = sd;
}
}
/**
*
* @param args
*/
public static void main(String[] args) {
Dog aDog = new Dog("Max");
// we pass the object to foo
foo(aDog);
Dog oldDog = aDog;
System.out.println(" 1: " + aDog.getName().equals("Max")); // false
System.out.println(" 2 " + aDog.getName().equals("huahua")); // false
System.out.println(" 3 " + aDog.getName().equals("moron")); // true
System.out.println(" 4 " + " " + (aDog == oldDog)); // true
// part2
Dog aDog1 = new Dog("Max");
foo(aDog1, 5);
Dog oldDog1 = aDog;
System.out.println(" 5 : " + aDog1.getName().equals("huahua")); // true
System.out.println(" part2 : " + (aDog1 == oldDog1)); // false
Dog oldDog2 = foo(aDog1, 5, 6);
System.out.println(" 6 " + (aDog1 == oldDog2)); // true
System.out.println(" 7 " + (aDog1 == oldDog)); // false
System.out.println(" 8 " + (aDog == oldDog2)); // false
}
/**
*
* @param d
*/
public static void foo(Dog d) {
System.out.println(d.getName().equals("Max")); // true
d.setName("moron");
d = new Dog("huahua");
System.out.println(" -:- " + d.getName().equals("huahua")); // true
}
/**
*
* @param d
* @param a
*/
public static void foo(Dog d, int a) {
d.getName().equals("Max"); // true
d.setName("huahua");
}
/**
*
* @param d
* @param a
* @param b
* @return
*/
public static Dog foo(Dog d, int a, int b) {
d.getName().equals("Max"); // true
d.setName("huahua");
return d;
}
}
The sample code to demonstrate the impact of changes to the object at different functions .
I think this simple explanation might help you understand as I wanted to understand this same thing when I was struggling through this.
When you pass a primitive data to a function call it's content is being copied to the function's argument and when you pass an object it's reference is being copied to the function's argument. Speaking of object, you can't change the copied reference-the argument variable is referencing to in the calling function.
Consider this simple example, String is an object in java and when you change the content of a string the reference variable will now point to some new reference as String objects are immutable in java.
String name="Mehrose"; // name referencing to 100
ChangeContenet(String name){
name="Michael"; // refernce has changed to 1001
}
System.out.print(name); //displays Mehrose
Fairly simple because as I mentioned you are not allowed to change the copied reference in the calling function. But the problem is with the array when you pass an array of String/Object. Let us see.
String names[]={"Mehrose","Michael"};
changeContent(String[] names){
names[0]="Rose";
names[1]="Janet"
}
System.out.println(Arrays.toString(names)); //displays [Rose,Janet]
As we said that we can't change the copied reference in the function call and we also have seen in the case of a single String object. The reason is names[] variable referencing to let's say 200 and names[0] referencing to 205 and so on. You see we didn't change the names[] reference it still points to the old same reference still after the function call but now names[0] and names[1] reference has been changed. We Still stand on our definition that we can't change the reference variable's reference so we didn't.
The same thing happens when you pass a Student object to a method and you are still able to change the Student name or other attributes, the point is we are not changing the actual Student object rather we are changing the contents of it
You can't do this
Student student1= new Student("Mehrose");
changeContent(Student Obj){
obj= new Student("Michael") //invalid
obj.setName("Michael") //valid
}
Java uses pass-by-value, but the effects differ whether you are using primitive or a reference type.
When you pass a primitive type as an argument to a method, it's getting a copy of the primitive and any changes inside the block of the method won't change the original variable.
When you pass a reference type as an argument to a method, it's still getting a copy but it's a copy of the reference to the object (in other words, you are getting a copy of the memory address in the heap where the object is located), so any changes in the object inside the block of the method will affect the original object outside the block.
The Java programming language passes arguments only by value, that is, you cannot change the argument value in the calling method from within the called method.
However, when an object instance is passed as an argument to a method, the value of the argument is not the object itself but a reference to the object. You can change the contents of the object in the called method but not the object reference.
To many people, this looks like pass-by-reference, and behaviorally, it has much in common with pass-by-reference. However, there are two reasons this is inaccurate.
Firstly, the ability to change the thing passed into a method only applies to objects, not primitive values.
Second, the actual value associated with a variable of object type is the reference to the object, and not the object itself. This is an important distinction in other ways, and if clearly understood, is entirely supporting of the point that the Java programming language passes arguments by value.
The following code example illustrates this point:
1 public class PassTest {
2
3 // Methods to change the current values
4 public static void changeInt(int value) {
5 value = 55;
6 }
7 public static void changeObjectRef(MyDate ref) {
8 ref = new MyDate(1, 1, 2000);
9 }
10 public static void changeObjectAttr(MyDate ref) {
11 ref.setDay(4);
12 }
13
14 public static void main(String args[]) {
15 MyDate date;
16 int val;
17
18 // Assign the int
19 val = 11;
20 // Try to change it
21 changeInt(val);
22 // What is the current value?
23 System.out.println("Int value is: " + val);
24
25 // Assign the date
26 date = new MyDate(22, 7, 1964);
27 // Try to change it
28 changeObjectRef(date);
29 // What is the current value?
30 System.out.println("MyDate: " + date);
31
32 // Now change the day attribute
33 // through the object reference
34 changeObjectAttr(date);
35 // What is the current value?
36 System.out.println("MyDate: " + date);
37 }
38 }
This code outputs the following:
java PassTest
Int value is: 11
MyDate: 22-7-1964
MyDate: 4-7-1964
The MyDate object is not changed by the changeObjectRef method;
however, the changeObjectAttr method changes the day attribute of the
MyDate object.
There are only two versions:
Java passes primivates as values and objects as addresses. Those who say, "address are values too", do not make a distinction between the two. Those who focus on the effect of the swap functions focus on what happens after the passing is done.
In C++ you can do the following:
Point p = Point(4,5);
This reserves 8 bytes on the stack and stores (4,5) in it.
Point *x = &p;
This reserves 4 bytes on the stack and stores 0xF43A in it.
Point &y = p;
This reserves 4 bytes on the stack and stores 0xF43A in it.
I think everyone will agree that a call to f(p) is a pass-by-value if the definition of f is f(Point p). In this case an additional 8 bytes being reserved and (4,5) being copied into it. When f changes p the the the original is guarantieed to be unchanged when f returns.
I think that everyone will agree that a call to f(p) is a pass-by-reference if the definition of f is f(Point &p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes p the the original is guarantieed to be changed when f returns.
A call to f(&p) is also pass-by-reference if the definition of f is f(Point *p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes *p the the original is guarantieed to be changed when f returns.
A call to f(x) is also pass-by-reference if the definition of f is f(Point *p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes *p the the original is guarantieed to be changed when f returns.
A call to f(y) is also pass-by-reference if the definition of f is f(Point &p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes p the the original is guarantieed to be changed when f returns.
Sure what happens after the passing is done differs, but that is only a language construct. In the case of pointer you have to use -> to access the members and in the case of references you have to use .. If you want to swap the values of the original then you can do tmp=a; a=b; b=tmp; in the case of references and tmp=*a; *b=tmp; *a=tmp for pointers. And in Java you would have do: tmp.set(a); a.set(b); b.set(tmp). Focussing on the assignment statement statement is silly. You can do the exact same thing in Java if you write a little bit of code.
So Java passes primivates by values and objects by references. And Java copy values to achieve that, but so does C++.
For completeness:
Point p = new Point(4,5);
This reserves 4 bytes on the stack and stores 0xF43A in it and reserves 8 bytes on the heap and stores (4,5) in it.
If you want to swap the memory locations like so
void swap(int& a, int& b) {
int *tmp = &a;
&a = &b;
&b = tmp;
}
Then you will find that you run into the limitations of your hardware.
Guess, the common canon is wrong based on inaccurate language
Authors of a programming language do not have the authority to rename established programming concept.
Primitive Java types byte, char, short, int, long float, double are definitely passed by value.
All other types are Objects: Object members and parameters technically are references.
So these "references" are passed "by value", but there occurs no object construction on the stack. Any change of object members (or elements in case of an array) apply to the same original Object; such reference precisely meets the logic of pointer of an instance passed to some function in any C-dialect, where we used to call this passing an object by reference
Especially we do have this thing java.lang.NullPointerException, which makes no sense in a pure by-value-concept
If you want it to put into a single sentence to understand and remember easily, simplest answer:
Java is always pass the value with a new reference
(So you can modify the original object but can not access the original reference)
Every single answer here is tying to take pass pointer by reference from other languages and show how it is impossible to do in Java. For whatever reason nobody is attempting to show how to implement pass-object-by-value from other languages.
This code shows how something like this can be done:
public class Test
{
private static void needValue(SomeObject so) throws CloneNotSupportedException
{
SomeObject internalObject = so.clone();
so=null;
// now we can edit internalObject safely.
internalObject.set(999);
}
public static void main(String[] args)
{
SomeObject o = new SomeObject(5);
System.out.println(o);
try
{
needValue(o);
}
catch(CloneNotSupportedException e)
{
System.out.println("Apparently we cannot clone this");
}
System.out.println(o);
}
}
public class SomeObject implements Cloneable
{
private int val;
public SomeObject(int val)
{
this.val = val;
}
public void set(int val)
{
this.val = val;
}
public SomeObject clone()
{
return new SomeObject(val);
}
public String toString()
{
return Integer.toString(val);
}
}
Here we have a function needValue and what it does is right away create a clone of the object, which needs be implemented in the class of the object itself and the class needs to be marked as Cloneable. It is not essential to set so to null after that, but i have done so here to show that we are not going to be using that reference after that.
It may well be that Java does not have pass-by-reference semantics, but to call the language "pass-by-value" is along the lines of wishful thinking.
After following an exhaustive discussion, I think it's time to put all serious results together in a snippet.
/**
*
* @author Sam Ginrich
*
* All Rights Reserved!
*
*/
public class JavaIsPassByValue
{
static class SomeClass
{
int someValue;
public SomeClass(int someValue)
{
this.someValue = someValue;
}
}
static void passReferenceByValue(SomeClass someObject)
{
if (someObject == null)
{
throw new NullPointerException(
"This Object Reference was passed by Value,\r\n that's why you don't get a value from it.");
}
someObject.someValue = 49;
}
public static void main(String[] args)
{
SomeClass someObject = new SomeClass(27);
System.out.println("Here is the original value: " + someObject.someValue);
passReferenceByValue(someObject);
System.out.println(
"\nAs ´Java is pass by value´,\r\n everything without exception is passed by value\r\n and so an object's attribute cannot change: "
+ someObject.someValue);
System.out.println();
passReferenceByValue(null);
}
}
One can easily see from the output, that in Java everything is passed by value, so simple!
Here is the original value: 27
As ´Java is pass by value´,
everything without exception is passed by value
and so an object´s attribute cannot change: 49
'Exception in thread "main" java.lang.NullPointerException: This Object Reference was passed by value,
that´s why you don´t get a value from it.
at JavaIsPassByValue.passReferenceByValue(JavaIsPassByValue.java:26)
at JavaIsPassByValue.main(JavaIsPassByValue.java:43)
"I am a Junior Java Developer and I would like to know if Java uses Call-by-Value or Call-by-Reference?"
There is no universal answer to that and there cannot be for it's a false dichotomy. We have 2 different terms (Call-by-Value/Call-by-Reference) but at least 3(!) different ways of handling said data when passing it to a method:
int in Java or C++ or C#.)It's uncontentious in the OO world that #1 is Call-by-Value and #2 is Call-by-Reference. However, since we have only two terms for three options, there is no clear delineation between the two terms, thanks to option #3.
"What does that mean for me?"
It means that within the Java sphere you may reasonably assume #3 to be assumed under Call-by-Value (or the more verbal gymnastics term, Call-References-by-Value).
However, in the wider OO world, it means you have to ask for an explicit delineation between Call-by-Value and Call-by-Reference, specifically how the other party classifies #3.
"But I read that the JLS defines it as Call-by-Value!"
Which is why your initial assumption when dealing with Java developers should be the above. The JLS has much less authority outside of Java, however.
"Why would Java developers insist on their own terminology?"
It's not for me to speculate but I think it's fair to point out that there is some potential problems with #2 (what is clearly Call-by-Reference), as hinted at, leading to Call-by-Reference not having the best of reputation everywhere.
"Is there a solution to this mess?"
3 options, only 2 ubiquitous names. The obvious exit is a 3rd term that gains equal wide-spread use as Call-by-Value and Call-by-Reference (and which is less confusing than Call-References-by-Value, perhaps Call-by-Sharing). Until then you need to presume or ask, as outlined above.
Ultimately, it does not matter what we call it, for as long as we understand each other and there is no confusion.
Is Java a pass-by-value or reference? Prove it.
Java strictly enforces pass-by-value. Passing the parameters by using pass-by-values does not affect/alter the original variable. In the following program, we have initialized a variable called 'x' with some value and used the pass-by-value technique to demonstrate how the value of the variable remains unchanged.
Code:
public class Main
{
public static void main(String[] args)
{
//Original value of 'x' will remain unchanged
// in case of call-by-value
int x = 5;
System.out.println( "Value of x before call-by-value: " + x);
// 5
processData(x);
System.out.println("Value of x after call-by-value: " + x);
// 5
}
public static void processData(int x)
{
x=x+10;
}
}
Now coming to the meaning - the value of x did not change in the main function - this is called pass by value.
If the value changes in the main function it is called pass by reference.
difference between pass by value and pass by reference
What is Pass by Value?
In pass by value, the value of a function parameter is copied to another location of the memory. When accessing or modifying the variable within the function, it accesses only the copy. Thus, there is no effect on the original value.
What is Pass by Reference?
In pass by reference, the memory address is passed to that function. In other words, the function gets access to the actual variable.
Difference Between Pass by Value and Pass by Reference
Definition
Pass by value refers to a mechanism of copying the function parameter value to another variable while the pass by reference refers to a mechanism of passing the actual parameters to the function. Thus, this is the main difference between pass by value and pass by reference.
Changes
In pass by value, the changes made inside the function are not reflected in the original value. On the other hand, in pass by reference, the changes made inside the function are reflected in the original value. Hence, this is another difference between pass by value and pass by reference.
Actual Parameter
Moreover, pass by value makes a copy of the actual parameter. However, in pass by reference, the address of the actual parameter passes to the function.