Pass-by-Value Please (Cup Size continued)
If you haven't read the Cup Size story, this one won't make sense. Or it will make sense, but you'll think its really stupid. Or you won't think it's stupid but you'll find yourself... never mind, just go read it now and then come back.
I really care about my cups.
I don't want just anybody putting something in my cups. If I have something in a cup, I just want it to stay that way until I decide to change it! So back off!
So if a Java variable is a cup, with a value in it, what does it mean to "pass" a variable to a method? And are primitives and references treated the same way?
We'll get there, but first let's start with simple assignment.
What does it mean to say:
1) int x = 3;
2) int y = x;
In line 1, a cup called x, of size int, is created and given the value 3.
In line 2, a cup called y, of size int, is created and given the value... 3.
The x variable is not affected!
Java COPIES the value of x (which is 3) and puts that COPY into y.
This is PASS-BY-VALUE. Which you can think of as PASS-BY-COPY. The value is copied, and that's what gets shoved into the new cup. You don't stuff one cup into another one.
Saying int y = x does NOT mean "put the x cup into y". It means "copy the value inside x and put that copy into y".
If I later change y:
y = 34;
Is x affected? Of course not. The x cup is still sitting there, all happy.
If I later change x:
x = 90;
Is y affected? Nope. They are disconnected from one another once the assignment was made (the COPY was made).
SO... what about Reference Variables (remote controls)? How does THAT work?Not so tricky, in fact the rule is the same.
References do the same thing. You get a copy of the reference.
So if I say:
Cat A = new Cat();
Cat B = A;
The remote control in A is copied. Not the object it refers to.
You've still got just one Cat object.But now you have two different references (remote controls) controlling the same Cat object.
NOW let's look at passing values to methods
Java is pass-by-value.
Always.
That means "copy the value, and pass the copy."
For primitives, it's easy:
int x = 5;
doStuff(x); // pass a COPY of x (the value 5) to the doStuff method
The doStuff method looks like this:
void doStuff(int y) {
// use y in some way
}
A copy of the value in x, which is 5, is passed into the doStuff() method.
The doStuff() method has its own new cup, called y, waiting.The y cup is a new, different cup. With a copy of what was in x at the time it was passed. From this point on, y and x have no affect on each other. If you change y, you don't touch x.
void doStuff(int y) {
y = 27; // this does NOT affect x
}
And vice-versa. If you change x, you don't change y.
The only part x had in this whole business was to simply copy its value and send that copy into the doStuff() method.
How does pass-by-value work with references?
Way too many people say "Java passes primitive by value and objects by reference". This is not the way it should be stated. Java passes everything by value. With primitives, you get a copy of the contents. With references you get a copy of the contents.
But what is the contents of a reference?
The remote control. The means to control / access the object.
When you pass an object reference into a method, you are passing a COPY of the REFERENCE. A clone of the remote control. The object is still sitting out there, waiting for someone to use a remote.The object doesn't care how many remotes are "programmed" to control it. Only the garbage collector cares (and you, the programmer).
So when you say:
Cat A = new Cat();
doStuff(A);
void doStuff(Cat B) {
// use B in some way
}
There is still just ONE Cat object. But now TWO remote controls (references) can access that same Cat object.
So now, anything that B does to the Cat, will affect the Cat that A refers to, but it won't affect the A cup!
You can change the Cat, using your new B reference (copied directly from A), but you can't change A.
What the heck does that mean?
You can change the object A refers to, but you can't take the A reference variable and do something to it -- like redirect it to reference a different object, or null.
So if you change the B reference (not the Cat object B refers to, but the B reference itself) you don't change A. And the opposite is true.
So...
Cat A = new Cat();
doStuff(A);
void doStuff(Cat B) {
B = new Cat(); //did NOT affect the A reference
}
Doing this simply "points" B to control a different object. A is still happy.
So repeat after me:
Java is pass-by-value.
(OK, once again... with feeling.)
Java is pass-by-value.
For primitives, you pass a copy of the actual value.
For references to objects, you pass a copy of the reference (the remote control).
You never pass the object. All objects are stored on the heap. Always.
Now go have an extra big cup of coffee and write some code.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Cup Size -- a story about variables
The Coffee Corral coffeehouse at the Ranch is famous around these parts for its unique cup collection. If you really need to understand the way values and objects are used in Java, you gotta start here.
I like cups. Big cups, little cups. Painted tea cups, huge cappuccino bowls, cups with logos from the UCLA coffeehouse. Cups I painted myself at the "All Fired Up" pottery shop. Cups with curvy, sexy handles. Metallic cups that I now know must never, ever go in the microwave.
So when I think of variables, I naturally think of... cups.
A variable is just a cup. It has a size, and it can hold something.
In Java, cups come in two main styles: primitive and reference.
Primitive cups hold primitive values.
Reference cups hold remote controls to objects.
We'll start with primitives. Primitive cups are like the cups they have at the coffeehouse. If you're familiar with Starbucks' you know what I mean. They come in different sizes, and each size has a name like short, tall, grande. As in, "I'd like a grande mocha java with extra whipped cream. Oh, and use non-fat milk please")
Our coffeehouse has a picture of the cups on the counter, so customers know what to order. It looks like this:
In Java, integer primitives comes in different sizes, and those sizes have names. They look like this:
These cups hold a value.
So instead of saying, "I'd like a tall French Roast", you say to the compiler, "I'd like an int with the number 90 please." And that's what you get. (you also have to give your cup a name, but we'll get to that later.)
The number 90 is dropped into your int-sized cup.
But what about floating point numbers? (the things with decimal points)
They get their own cups too.
And there's another cup for booleans, that can store values of true or false. And a cup for chars, that store single characters like the letter 'c' or 'z'.
In Java, each of these cups (float, char, long, etc.) is a specific size. Byte is the smallest, double and long are the largest. Rather than measure in milliliters (or ounces as we do in the US) Java variables have a size measured in bits:
byte - 8 bits
short - 16 bits
int - 32 bits
long - 64 bits
All of these integer types are SIGNED. The leftmost bit represents the sign (positive or negative) and is NOT part of the value. So with a byte, for instance, you don't get the whole 8 bits to represent your value. You get 7. This gives you a range, for bytes, of :
(-2 to the 7th) through (2 to the 7th) -1. Why that little -1 on the end? Because zero is in there, and zero counts as negative. Works the same way with the others.
float - 32 bits
double - 64 bits
Floating point numbers are in the IEEE 754 standard. If that means anything to you, great. If it doesn't, well, then, you'll just have to struggle through the long technical dissertation on floating point numbers which I feel compelled to insert here. What the heck, I'll skip it.
We rejoin our primitive variables, already in progress.
char - 16 bits, UNSIGNED
(Unicode format -- for English, it maps perfectly to ASCII with the high 8-bits just hanging out as a bunch of zeros)
boolean - hmmmm... you're not supposed to ask. It holds a value of true or false, but it's really stored as a numeric value, probably in a byte-sized cup. Try not to think about the size; all you know is that it holds a boolean.
Let's get to the Really Interesting Cups... REFERENCES
In Java, if you want to stick an object in a variable, remember that the object is created out on the garbage-collectible heap. Always. So it's not IN the variable. There aren't giant, expandable cups which can be made big enough to hold any object. And unlike C/C++, there aren't cups which hold the exact memory location of the object.
In Java, objects are created on the heap, and a REFERENCE to the object is stored in the cup. Think of it as a remote control to a specific type of object.
At the CoffeeCorral, a customer can ask for a remote control to a TV They ask for it like this:
"I'd like a reference to a new Sony32 television please, and name it TV." which in Java looks like:
But notice the NAME written on the cup. The cups have unique names. Imagine if you had a pile of remote controls, and nobody knew which one controlled which TV. So we make people put names on their remote control cups. But the name is not on the object -- the object has a unique ID, like a serial number, but that isn't the same as what you name the reference! The reference name (the name on the cup) is YOUR choice.
It's the same for primitives -- you name the cups like this:
"I'd like a byte with the number 7, and name it x please".
For object references, you can also ask for a self-serve remote control... a remote control where you don't have a television object picked out yet. You still get the remote in the cup, but you "program" that remote for a specific television later.
In Java you say:
Sony32 tv; // declare but don't initialize with an actual Sony32 object.
It's like saying, "I'd like a reference to a Sony32 television, and name the remote 'tv', but I'll pick out the actual television later.". You get the cup, you get the remote, but there's no object and the remote isn't controlling ANYTHING.
In Java, a remote which refers to nothing is a reference with a value of null.
So what's REALLY inside that cup? What's a remote control?
In Java, remote controls are called references. They store a value which the Java Virtual Machine (JVM) uses to get to your object. It sure looks and feels a lot like a pointer, and it might very well be a pointer to a pointer, or...
You Can't Know. It's an implementation detail that you, as a programmer, can't access. Don't even think about it. There's no way to use that value other than to access the methods and variables of the actual object the reference refers to. That's part of what makes Java safer than C/C++. You can not go directly to any arbitrary memory location. The JVM allocates memory on your behalf, for your object, and stores an address-like thing in the reference cup (which is most likely a 32-bit cup, but not guaranteed to be).
If this depresses you, take a deep breath, have a nice big cup of hot tea and get over it. When you start doing CORBA you'll be grateful beyond belief that you don't have to take care of the memory.
We'll get there, but first let's start with simple assignment.
You've still got just one Cat object.But now you have two different references (remote controls) controlling the same Cat object.
doStuff(x); // pass a COPY of x (the value 5) to the doStuff method
}
}
doStuff(A);
}
doStuff(A);
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Cup Size -- a story about variables
The Coffee Corral coffeehouse at the Ranch is famous around these parts for its unique cup collection. If you really need to understand the way values and objects are used in Java, you gotta start here.
I like cups. Big cups, little cups. Painted tea cups, huge cappuccino bowls, cups with logos from the UCLA coffeehouse. Cups I painted myself at the "All Fired Up" pottery shop. Cups with curvy, sexy handles. Metallic cups that I now know must never, ever go in the microwave.
So when I think of variables, I naturally think of... cups.
A variable is just a cup. It has a size, and it can hold something.
In Java, cups come in two main styles: primitive and reference.
Primitive cups hold primitive values.
Reference cups hold remote controls to objects.
We'll start with primitives. Primitive cups are like the cups they have at the coffeehouse. If you're familiar with Starbucks' you know what I mean. They come in different sizes, and each size has a name like short, tall, grande. As in, "I'd like a grande mocha java with extra whipped cream. Oh, and use non-fat milk please")
Our coffeehouse has a picture of the cups on the counter, so customers know what to order. It looks like this:
These cups hold a value.
So instead of saying, "I'd like a tall French Roast", you say to the compiler, "I'd like an int with the number 90 please." And that's what you get. (you also have to give your cup a name, but we'll get to that later.)
So instead of saying, "I'd like a tall French Roast", you say to the compiler, "I'd like an int with the number 90 please." And that's what you get. (you also have to give your cup a name, but we'll get to that later.)
The number 90 is dropped into your int-sized cup.
But what about floating point numbers? (the things with decimal points)
They get their own cups too.
They get their own cups too.
And there's another cup for booleans, that can store values of true or false. And a cup for chars, that store single characters like the letter 'c' or 'z'.
In Java, each of these cups (float, char, long, etc.) is a specific size. Byte is the smallest, double and long are the largest. Rather than measure in milliliters (or ounces as we do in the US) Java variables have a size measured in bits:
byte - 8 bits
short - 16 bits
int - 32 bits
long - 64 bits
short - 16 bits
int - 32 bits
long - 64 bits
All of these integer types are SIGNED. The leftmost bit represents the sign (positive or negative) and is NOT part of the value. So with a byte, for instance, you don't get the whole 8 bits to represent your value. You get 7. This gives you a range, for bytes, of :
(-2 to the 7th) through (2 to the 7th) -1. Why that little -1 on the end? Because zero is in there, and zero counts as negative. Works the same way with the others.
(-2 to the 7th) through (2 to the 7th) -1. Why that little -1 on the end? Because zero is in there, and zero counts as negative. Works the same way with the others.
float - 32 bits
double - 64 bits
double - 64 bits
Floating point numbers are in the IEEE 754 standard. If that means anything to you, great. If it doesn't, well, then, you'll just have to struggle through the long technical dissertation on floating point numbers which I feel compelled to insert here. What the heck, I'll skip it.
We rejoin our primitive variables, already in progress.
char - 16 bits, UNSIGNED
(Unicode format -- for English, it maps perfectly to ASCII with the high 8-bits just hanging out as a bunch of zeros)
(Unicode format -- for English, it maps perfectly to ASCII with the high 8-bits just hanging out as a bunch of zeros)
boolean - hmmmm... you're not supposed to ask. It holds a value of true or false, but it's really stored as a numeric value, probably in a byte-sized cup. Try not to think about the size; all you know is that it holds a boolean.
Let's get to the Really Interesting Cups... REFERENCES
In Java, if you want to stick an object in a variable, remember that the object is created out on the garbage-collectible heap. Always. So it's not IN the variable. There aren't giant, expandable cups which can be made big enough to hold any object. And unlike C/C++, there aren't cups which hold the exact memory location of the object.
In Java, objects are created on the heap, and a REFERENCE to the object is stored in the cup. Think of it as a remote control to a specific type of object.
At the CoffeeCorral, a customer can ask for a remote control to a TV They ask for it like this:
"I'd like a reference to a new Sony32 television please, and name it TV." which in Java looks like:
But notice the NAME written on the cup. The cups have unique names. Imagine if you had a pile of remote controls, and nobody knew which one controlled which TV. So we make people put names on their remote control cups. But the name is not on the object -- the object has a unique ID, like a serial number, but that isn't the same as what you name the reference! The reference name (the name on the cup) is YOUR choice.
It's the same for primitives -- you name the cups like this:
"I'd like a byte with the number 7, and name it x please".
"I'd like a byte with the number 7, and name it x please".
For object references, you can also ask for a self-serve remote control... a remote control where you don't have a television object picked out yet. You still get the remote in the cup, but you "program" that remote for a specific television later.
In Java you say:
Sony32 tv; // declare but don't initialize with an actual Sony32 object.
It's like saying, "I'd like a reference to a Sony32 television, and name the remote 'tv', but I'll pick out the actual television later.". You get the cup, you get the remote, but there's no object and the remote isn't controlling ANYTHING.
In Java, a remote which refers to nothing is a reference with a value of null.
So what's REALLY inside that cup? What's a remote control?
In Java, remote controls are called references. They store a value which the Java Virtual Machine (JVM) uses to get to your object. It sure looks and feels a lot like a pointer, and it might very well be a pointer to a pointer, or...
You Can't Know. It's an implementation detail that you, as a programmer, can't access. Don't even think about it. There's no way to use that value other than to access the methods and variables of the actual object the reference refers to. That's part of what makes Java safer than C/C++. You can not go directly to any arbitrary memory location. The JVM allocates memory on your behalf, for your object, and stores an address-like thing in the reference cup (which is most likely a 32-bit cup, but not guaranteed to be).
If this depresses you, take a deep breath, have a nice big cup of hot tea and get over it. When you start doing CORBA you'll be grateful beyond belief that you don't have to take care of the memory.
Passing by value: This method copies the value of an argument into the formal parameter of the subroutine.
Passing by reference: In this method, a reference to an argument (not the value of the argument) is passed to the parameter.
Does Java pass by reference or by value?
Java passes everything by value, and not by reference – make sure you remember that. And when we say everything, we mean everything – objects, arrays (which are objects in Java), primitive types (like ints and floats), etc. – these are all passed by value in Java. What is the difference between pass by value and pass by reference? When passing an argument (or even multiple arguments) to a method, Java will create a copy or copies of the values inside the original variable(s) and pass that to the method as arguments – and that is why it is called pass by value. The key with pass by value is that the method will not receive the actual variable that is being passed – but just a copy of the value being stored inside the variable. So, how does this affect the code you write? Well, this is best illustrated by a simple and easy to understand example.
Example of pass by value in Java
Suppose we have a method that is named “Receiving” and it expects an integer to be passed to it:
public void Receiving (int var) { var = var + 2; }
Note that the “var” variable has 2 added to it. Now, suppose that we have some code which calls the method Receiving:
public static void main(String [] args) { int passing = 3; Receiving (passing); System.out.println("The value of passing is: " + passing); }
In the main method, we set the variable “passing” to 3, and then pass that variable to the Receiving method, which then adds 2 to the variable passed in.
What do you think the “System.out.println” call will print out? Well, if you thought it would print out a “5” you are wrong. It will actually print out a “3”. Why does it print out a 3 when we clearly added a 2 to the value in the Receiving method?
The reason it prints out a “3” is because Java passes arguments by value – which means that when the call to “Receiving” is made, Java will just create a copy of the “passing” variable and that copy is what gets passed to the Receiving method – and not the original variable stored in the “main” method. This is why whatever happens to “var” inside the Receiving method does not affect the “passing” variable inside the main method.
How does pass by value work?
Java basically creates another integer variable with the value of 3, and passes that to the “Receiving” method. That is why it is called “pass by value” – because the value of 3 is what is being passed to the “Receiving” method, not a reference to the “passing” variable.
Are objects passed by reference in Java?
As we said in the beginning of this article – everything is passed by value in Java. So, objects are notpassed by reference in Java. Let’s be a little bit more specific by what we mean here: objects are passed by reference – meaning that a reference/memory address is passed when an object is assigned to another – BUT (and this is what’s important) that reference is actually passed by value. The reference is passed by value because a copy of the reference value is created and passed into the other object – read this entire article and this will make a lot more sense. So objects are still passed by value in Java, just like everything else.
One other very important thing to know is that a variable of a class type stores an address of the object, and not the object itself. The object itself is stored at the address which the variable points to. Let’s suppose we have a class called SomeClass and that we instantiate it with a variable of the SomeClass type. So, suppose we have the following very simple code:
SomeClass someVar;
The someVar variable above is a variable of a class type – which is commonly referred to as an object. But, what actually happens behind the scenes is that someVar will just contain a reference – which is basically a memory address that points to the real object and all the class variables for that object actually lives. So, remember that a variable of a class type – or what is commonly referred to as an object of a class – really just stores a memory address that points to the real object. Bottom line: anytime you see a variable of a class type like the someVar variable above, just remember that it is basically a reference that stores an address in memory.
Confused yet?
An example and some diagrams will help make this very clear. Suppose we have a class called PersonClass, which has a method called set that just sets the name and age for a given Person object. The details of the class itself don’t matter for the purpose of this example so we won’t bother to show the implementation of PersonClass. Now, let’s say we have the following code:
An example and some diagrams will help make this very clear. Suppose we have a class called PersonClass, which has a method called set that just sets the name and age for a given Person object. The details of the class itself don’t matter for the purpose of this example so we won’t bother to show the implementation of PersonClass. Now, let’s say we have the following code:
//create an object by passing in a name and age: PersonClass variable1 = new PersonClass("Mary", 32); PersonClass variable2; // Both variable2 and variable1 now both name the same object variable2 = variable1; /*this also changes variable1, since variable 2 and variable1 name the same exact object: */ variable2.set("Jack", 22); System.out.println(variable1);
Let’s just assume that System.out.println method above will print the name and age of a PersonClass object – even though this is not correct, it does keep the example simple and easy to understand. So, if we run the code above, the output will be:
Jack 22
In the code above, you can see that when we made a change to variable2, that it also changed variable1. This might confuse you into thinking that because of that fact Java is pass by reference – and you would be very WRONG. Both variable1 and variable2 hold a reference to the same object in memory – and this happened when we ran this line of code “variable2 = variable1″. When we use the assignment operator (the “=”) with variables of a class type, then we are copying that reference value – in other words variable2 is given the memory address (or reference) that is being stored in variable1. Remember that the word reference means the same thing as memory address. This assignment of references is best displayed by actual drawings, which we show below:
An illustration of pass by value in Java
So, looking at the images above it should be clear that variable1 and variable2 are just two different references to the same exact spot in memory. Because of the fact that the statement “variable2 = variable1″ essentially just copies the reference from variable1 into variable2, this is pass by value. You should think of the reference (which is a memory address) as the value, and in this case that reference is what is being copied. And, that is exactly what pass by value means – a copy of a value is passed to another variable. You should also read our article on the differences between primitive types and reference types here: Primitive type vs Reference type.
Let’s go through one last example. Let’s say we have the following code:
//create an object by passing in a name and age: PersonClass variable1 = new PersonClass("Mary", 32); PersonClass variable2; //Both variable2 and variable1 now reference the same object variable2 = variable1; PersonClass variable3 = new PersonClass("Andre", 45); // variable1 now points to variable3 variable1 = variable3; //WHAT IS OUTPUT BY THIS? System.out.println(variable2); System.out.println(variable1);
If we run the code above it will output the code below:
Mary 32 Andre 45
The key to understanding the code above is the fact that changing the object that variable1 points to does not change variable2. So, even though variable1 is changed to point to a different object, that has no effect whatsoever on variable2. Hopefully that is clear to you – that variable1 and variable2 are not interchangeable – they are different variables that just store the same value – at least until the “variable1 = variable3″ statement. And that should prove to you that Java passes objects by value, and everything else for that matter.
Is it possible to pass an object by reference in Java?
No, there are no “extra” language features in Java that would allow for you to pass an object by reference in Java. Java is strictly pass by value, and does not give the programmer the option of passing anything by reference.
Are arrays passed by reference in Java?
Arrays in Java are also objects. And what did you learn about objects in Java? Well, that they are passed by value and not passed by reference. And the same is true for arrays in Java – they are passed by value and not by reference. Of course, like any other class object, when an array is passed to another method that method can still change the contents of the array itself. But, what is being passed to the method is a copy of the reference address that points to the array object. Just take a look at our example above for the PersonClass – the same exact principles apply to arrays since they are objects in Java, and are passed by value.
Java Pass By Value and Pass By Reference
Java uses pass by value. There is no pass by reference in Java. This Java tutorial is to walk you through the difference between pass by value and pass by reference, then explore on how Java uses pass by value with examples. Most importantly we need to be clear on what we mean by using the terminology “pass by value” and “pass by reference”. Some people are saying that in Java primitives are passed by value and objects are passed by reference. It is not correct.
Pass by Value
Let us understand what is pass by value. Actual parameter expressions that are passed to a method are evaluated and a value is derived. Then this value is stored in a location and then it becomes the formal parameter to the invoked method. This mechanism is called pass by value and Java uses it.
Pass by Reference
In pass by reference, the formal parameter is just an alias to the actual parameter. It refers to the actual argument. Any changes done to the formal argument will reflect in actual argument and vice versa.
Java Language Specification Says
In Java Language Specification 8.4.1. Formal Parameters section it is stated that,
“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.”
It is clearly evident that the actual argument expressions are evaluated and values given to the method body as formal parameters. When an object is passed as argument, that object itself is not passed as argument to the invoked method. Internally that object’s reference is passed as value and it becomes the formal parameter in the method.
Java uses JVM Stack memory to create the new objects that are formal parameters. This newly created objects scope is within the boundary of the method execution. Once the method execution is complete, this memory can be reclaimed.
Test Pass by Value vs Pass by Reference
We can run a simple swap test and check for pass by value vs pass by reference. Let us pass two arguments and swap them inside the invoked method, then check if the actual arguments are swapped. If the actual arguments are affected then the mechanism used is pass by reference otherwise it is pass by value.
public class Swap { public static void main(String args[]) { Animal a1 = new Animal("Lion"); Animal a2 = new Animal("Crocodile"); System.out.println("Before Swap:- a1:" + a1 + "; a2:" + a2); swap(a1, a2); System.out.println("After Swap:- a1:" + a1 + "; a2:" + a2); } public static void swap(Animal animal1, Animal animal2) { Animal temp = new Animal(""); temp = animal1; animal1 = animal2; animal2 = temp; } } class Animal { String name; public Animal(String name) { this.name = name; } public String toString() { return name; } }
Example Output:
Before Swap:- a1:Lion; a2:Crocodile After Swap:- a1:Lion; a2:Crocodile
Objects are not swapped because Java uses pass by value.
Swap in C++:
Same code will swap the objects in C++ since it uses pass by reference.
void swap(Type& arg1, Type& arg2) { Type temp = arg1; arg1 = arg2; arg2 = temp; }
Does Java Passes the Reference?
Everything is simple and then why is this topic so hot? Now let us look at the following code where we able to change the property of a passed argument object inside a method and it gets reflected in the actual argument.
public class Swap { public static void main(String args[]) { Animal a = new Animal("Lion"); System.out.println("Before Modify: " + a); modify(a); System.out.println("After Modify: " + a); } public static void modify(Animal animal) { animal.setName("Tiger"); } } class Animal { String name; public Animal(String name) { this.name = name; } public String toString() { return name; } public void setName(String name) { this.name = name; } }
Example Output:
Before Modify: Lion After Modify: Tiger
If the arguments are passed by value then how we are able to change an attribute of the passed argument? This is because Java passes the object reference ‘by value’. When an object is passed as argument to a method, actually the reference to that object is passed. The formal parameter is a mapping of the reference to the actual parameter.
Java Passes Reference by Value
Following figures explains method scope for variables with respect to call by value. Consider the numbers 100, 200, 600 and 700 as pointers to memory location, these are logical only and for your understanding.
In figure 1, there are two objects with variable name a1, a2 which references the location 100 and 200 respectively.
In figure 2, there are two objects named formal-arg1, formal-arg2 which references location 600 and 700 respectively. Here is the catch, contents of the location 600, 700 are again references to another location 100 and 200. So the called method has got the reference of the passed arguments. Using the reference it can manipulate only the contents of the actual argument object. But it cannot change the fact that a1 points to 100 and a2 points to 200, that’s what we are trying to do when we swap the objects.
Important point to note is that “the reference is copied as a value” to a new variable and it is given as formal parameter to the called method. It does not get a1 variable which is the actual argument in scope. This is the key difference between pass by value and pass by reference
No comments:
Post a Comment