I read many articles and all says Java is pass by value. But i still don't construe the difference between pass by value and reference. I wrote a sample program and it executes like this..
public class PassByValue {
private int a;
private int b;
public PassByValue(int a, int b) {
this.a = a;
this.b = b;
}
public static int mul(int a, int b) {
int z = a * b;
System.out.println("The Value of Z inside mul: " + z);
return z;
}
public static void main(String args[]) {
int z = 100;
int x = 40;
int y = 20;
mul(x,y);
PassByValue pass = new PassByValue(x,y);
mul(pass.a,pass.b);
System.out.println("The Value of Z" + z);
}
}
Execution
800
800 and
100
Can anyone explain me these questions...
What is Pass By Value means...
Answer: Its just passing the numbers or value stored in the variable to a function. Am i right or wrong.
How do you say Java is Pass By Value?
Why is Java is Pass By Value and not by reference?
Does the above program Tries shows an example of Pass by value and Reference... but still does things via Pass by Value only... I wrote that program.
The confusion is probably due to the fact that a variable can't contain an object in the first place. A variable can only contain a reference to an object. (In other words, objects aren't passed at all, not by reference, not by value.)
Once you realize this, it is quite clear that nothing is pass-by-reference in Java. A variable refering to an object stores a reference, and this reference is passed by value.
1. What is Pass By Value means...
Answer: Its just passing the numbers or value stored in the variable to a function. Am i right or wrong.
That's right. The value contained in the variable is passed, and not the variable itself.
1. How do you say Java is Pass By Value?
Java is pass by value because primitives are passed by value, and references are passed by value. (Objects are never passed.)
You can't implement a swap method in Java for instance. I.e., you can't do
String str1 = "hello";
String str2 = "world";
swap(str1, str2);
// str1 can't refer to anything but "hello"
// str2 can't refer to anything but "world"
2. Why is Java is Pass By Value and not by reference?
As explained above, even references are passed by value.
You are right in your answer, but you are lacking detail. If you do
Dog d = new Dog()
d is a reference to an instance of Dog, i.e. What pass by value means is that you when pass d into a method
walkDog(d);
the a copy of the reference (i.e. the value of the reference, not the reference itself) to the Dog is passed into the method. So you have 2 references to the one instance of the Dog, the one in the calling scope, and the one in the called scope. Lets say in the walkDog method there is a line
d = new Dog();
the d reference in the method only points to the new Dog. The original reference where the method was first called still points to the original Dog. If Java had pass by reference, the same reference, not a copy of the reference would be used in the method, and so changing the value of the reference would affect the reference in both the calling and the called scope.
EDIT -- based on your comment, I want to make on thing clear. Since the reference in the original scope and the method scope both point to the same object, you can still change things on that object in both scopes. So if you do
d.drinkWater();
in the walkDog method, and drinkWater changes some variable on the dog object, then since both references point to the same object, which was changed.
It's only a distinction between what the references actually are in each scope. But it does come up a lot.
You can think of pass-by-value as passing only the value contained in the variable and not the variable itself. So then the value is copied into another temporary variable. In contrast, you can think of pass-by-reference as passing the actual variable and no temporary copies are made, so that any changes in the variable is 'saved'. Although there is more to it, it might be easier way to thinking about it
I think instead creeping around if Java supports pass by reference or values, one should be clear about the way of using the instances of the classes in Java in his implementation. It all happens to be the type of instances - mutable/immutable which is gonna decide the way we pass things to the functions! That's up to you to explore this difference!
Let me clarify my argument of why there is no need of chasing back at passing what?! Consider this...
First Code:
void foobar(int *a){
printf("%d", *a);
}
int main(){
int a = 5;
foobar(&a);
return 0;
}
Here in this C code, what are you passing... the address of the variable 'a'. This happens to be the pass by reference! :)
Let us consider another one...
Second Code:
void foobar(int* a){
printf("%d", *a);
}
int main(){
int a = 5;
int *p = &a;
foobar(p);
return 0;
}
Here in this C code, what am I passing....? The value of the variable 'p', doesn't matter whether it is pointer or something :P
So what do you call this as pass by value/pass by reference? I leave this to you! But all we need to look at is how we gonna implement... :)
So in Java... with what we pass we can say - It supports "Pass by value" or "Pass by reference of some instance" and not "Pass by reference"
***Only thing which I can clearly conclude is with the primitive data types in Java. Since there is no pointers with which one can edit the content of a byte without the actual variable, we can't have pass by reference for them(I mean the primitive data types) in Java.
Related
I read in this question that Java is always pass-by-value. And so even references are passed by value.
I don't understand what this means, can somebody clarify this for me please?
Given this
Object ref = new Object();
ref is actually storing a value, some address to an object. Let's say 1234.
When you pass ref around
public void method(Object passed) {...}
...
method(ref);
Java actually copies the value of the reference and assigns it to the parameter. So, passed will also have the value 1234.
Similarly, if you had
Object otherRef = ref;
the value 1234 would be copied and assigned to otherRef.
If you then re-assign otherRef, like
otherRef = new Object();
that would assign a new value to otherRef, but ref would still have the same value as before. That's what pass by value is.
When you call a method
ref.toString();
Java uses the value of the reference to find the referenced object and invoke the method. This is called dereferencing.
You might want to go through the JPDA javadoc, starting with StackFrame. Go through the fields and types and you'll start to understand how everything is mapped. For example, it has a getValues(..) method which returns a Map<LocalVariable, Value>. That should tell you that a variable doesn't actually store anything. Instead, it is mapped to a value, where that value may be all sorts of things.
int a = 5;
public void foo(int num) {
num = num + 5;
System.out.println(num);
}
foo(a);
System.out.println(a);
In the above code, a is passed into foo() by value. That means that a new variable is created with the scope of foo() that has the same initial value as a. When the value of num is changed, the value of a is not changed. The first println() will print a 10, the second will print a 5. In c++ you could pass a in by reference, which means that the value of a would be changed too.
I can try, in some other languages you have the option of passing something by a pointer (e.g. a reference to a memory region). Java calls every function with a value (not a pointer), but the value of an Object is a reference to a memory region. See also the default toString() in your own classes.
I always find this a good example:
Dog foo = new Dog("Rocky");
modifyDog(foo);
System.out.println(foo.name); //Alice
public void modifyDog(Dog aDog)
{
aDog.name = "Alice"; //here you change the field 'name' of the object located in memory currently referenced by foo and aDog variables.
aDog = new Dog(); //since aDog is a copy of foo then this won't recreate foo object
}
From my understand objects in java are passed by reference, or to be more exact, the references to objects are passed by value. So, if I declare a string and pass it into a function where I change the value of the string, why doesn't the original string change? For example:
class Thing
{
static void func(String x){ x = "new"; }
public static void main(String [] args)
{
String y = "old";
func(y);
System.out.print(y);
}
}
Why is the value of y still "old"?
EDIT: Why does the following set the attribute x of Thing something to 90?
class Thing { int x = 0;
static void func(Thing t){ t.x = 90; }
public static void main(String [] args){
Thing something = null;
something = new Thing();
func(something);
System.out.print(something.x);
}
}
First of all everything in java is pass by value. Even references are also pass by value.
You have created a new string literal and not returning that in the method func().
You are modifying the passed argument not the original string, hence you can't see the changes.
You might need this,
public static void main(String [] args)
{
String y = "old";
y= func(y);
System.out.print(y);
}
static String func(String x){
x = "new";
return x
}
Edit for the comment:
No they both are not Identical. There a lot of difference between two ways of String, especially in the memory aspect.
Read
Difference between Initializing string with new and " "
How can a string be initialized using " "?
Edit2:
In first case you are created a new string literal in the func method, but here you are modifying the reference.
Your doubt clarifies when you done
static void func(Thing t){
t = new Thing(); //as like previous example
t.x = 90; // points to new one. Not the original.
}
Now check the result.
It has nothing to do with immutability. It's all about how parameters are passed and the scope of variables.
Here is your function call
String y = "old"; // The reference y pointing to the string object "old": y ---> "old"
func(y);
and when you enter the called function
static void func(String x){ // x = y which means x now points to "old": x ---> "old"
x = "new"; // x ---> "new": now the local variable x is pointing to a different object. y still points to "old".
} //Scope of x ends here
When we print it
System.out.println(y);
y still points to "old". A new String object was assigned to x which was local to the method func. Therefore, it still prints "old".
As stated here:
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, if I declare a string and pass it into a function where I change
the value of the string, why doesn't the original string change?
The important thing to know is that you cannot declare a variable whose value is a string -- strings (which are objects) are not values in Java. y is a reference (a pointer to an object). The only types in Java are primitive types and reference types. The type String is a reference type.
Hence, you are passing y, a reference (a pointer to an object). Inside the function, x is likewise a reference (a pointer to an object). Changing the value of a reference (e.g. assigning (=) to x) never has any effect on the object it may have pointed to.
The . operator allows you to access a field of the object pointed to by a reference. Assigning to the result of a . access changes the object pointed to by the reference, not the reference itself. These are very different things.
In Java Objects and Strings are treated differently, Strings are kept immutable in JAVA.
To be more clear in your example:
Lets assume, String y is pointing to memory location 2000 and string x is pointing to memory
location 2001, so you get the same old value..
In case of objects please refer my example:
http://javaambition.blogspot.kr/2013/08/java-pass-by-value.html
I have come across two scenarios.
One in which an array is passed as argument to a method and if it is updated in the called method, it is reflecting in the calling method as well.
But in the second scenario, a String Object is passed as argument. The object is updated in the called method, but it doesn't reflect in the calling method.
I want to understand what is the difference between two, even though in both cases, value (of reference) is passed as argument. Please see below snippets.
Scenario 1:
class Test {
public static void main(String[] args){
int a[] = {3,4,5};
changeValue(a);
System.out.println("Value at Index 1 is "+a[1]);
}
public static void changeValue(int b[]){
b[1] = 9;
}
}
Output:
Value at Index 1 is 9
Here, reference (Memory Address) related to array a is passed to changeValue. Hence, b is just pointing to same address as a does.
Hence, whether I say b[1] or a[1], it is referring to same memory address.
Scenario 2:
public class Test {
public static void main(String[] args){
String value = "abc";
changeValue(value);
System.out.println(value);
}
public static void changeValue(String a){
a = "xyz";
}
}
Output:
abc
If I apply the same logic here, String Object VALUE's reference (Memory Address) is being passed to changeValue, which is recieved by a.
Hence, now a should be referring to the same memory location as VALUE does. Therefore, when a="xyz" is executed, it should replace "abc" with "xyz".
Can someone please point out where my understanding goes wrong? Thanks in advance!!
Java passes all its arguments by value. This means that a copy of the pointer to the String is made, and then passed to the method. The method then makes the pointer point at another object, but the original pointer still points to the same String.
This is not the same thing:
in the first example, you pass an array reference as an argument, therefore you correctly expect it to be changed by manipulating the reference directly;
in the second example however, you pass an object reference, sure -- but you change the reference itself in the method. Changes to a are not reflected when the method returns.
Consider any object:
public void changeObj(Object o)
{
o = new Whatever();
}
a new object is created, but it won't change o in the caller. The same happens here.
You're doing different things; with the string you set the parameter value, with the array you set something belonging to the reference.
For an equivalent array example you'd need to try setting the array reference to a new array:
public static void changeValue(int[] b) {
b = new int[] { 42, 60 };
}
The original array won't be changed.
The difference here is simple, and it is not actually about immutability of strings, as some other answers (now edited or deleted) might have originally implied. In one version (with the string), you have reassigned the reference, and in other version (with the array), you haven't.
array[0] = foo; // sets an element, no reassignment to variable
array = new int[] { 1,2,3 }; // assigns new array
obj = "hey"; // assigns new value
When you reassign the variable, you are not going to observe that change outside of the method. When you change elements of an array without reassigning the array variable, you will observe those changes. When you call a setter on an object without reassigning the actual variable of the object, you will observe those changes. When you overwrite the variable (new array, assigning new value, creating new object, etc.) those changes will go unobserved.
Arguments are passed (or copied) by value. The variable inside the method has the same value as the variable on the outside at the beginning. The variables are not linked, and they are not aliases for one another. They just happen to contain the same value. Once you reassign the value to one of them, that is no longer true! The variable on the outside is not affected by the variable on the inside, or even another local variable. Consider
Foo foo = new Foo();
Foo other = foo;
foo.setBar(1);
int bar = other.getBar(); // gets 1
foo = new Foo();
foo.setBar(42);
int bar2 = other.getBar(); // still gets 1
foo and other only referenced the same object for a time. Once foo was assigned a new object, the variables no longer had anything in common. The same is true for your reassignments to the parameter variable inside your method.
Thank you all for answers and updates..
I understood the difference between scenario 1 and 2 as below..
In scenario 1, the array reference is passed. The called method just updates one of the elements pointed by the reference.
While in scenario 2, the reference is passed, but when the called method assigns "xyz" to the reference variable (pointer), it actually creates a new String Object and its reference is assgined to a local reference variable 'a' (Pointer now points a different objct).
The code in called method is as good as
a = new String("xyz");
Hence, the object in called method and calling method are absolutely different and indepenedent and have no relation with each other.
The same could have happened with scenario 1, if instead of doing
b[1] = 9;
I would have used
b = new int[] {8,9,10};
I understood, Mutability fundamentals would have come in action, if I might have done like below..
String a="abc";
a="xyz";
In this case, object "abc" was being pointed by 'a'. When 'a' is assigned the duty to point to a new object "xyz", a new object "xyz" is created, which is not replacing the existing object "abc". i.e. "abc" is still existing but has no reference variable to keep itself accessible anymore. This non-replacement property is because of Immutability of String.
public static void main(String[] args) {
ArrayList a=null, b=null;
a=b;
a=new ArrayList();
System.out.println(a+""+b);
}
Why in the world b is printed as null ?
I thought java makes references the same then whatever you change in one of them reflects the other. But not in this case !!!
This line:
a = b;
Sets the value of a to the current value of b. That's all it does. The current value of b is null, so it's equivalent to:
a = null;
It does not associate the two variables. It just copies the value of one to another.
Changing the value of a afterwards does not change b at all. The two variables are entirely separate. Note that this is exactly the same for primitive types:
int a = 10;
int b = a;
a = 5;
System.out.println(b); // Prints 10, not 5
Even if you had:
ArrayList<String> a = new ArrayList<String>();
ArragList<String> b = a;
a.add("Hello");
System.out.println(b.get(0)); // Prints "Hello"
That's still not really showing a relationship between the variables a and b. They have the same value, so they refer to the same object (the ArrayList itself) - changes to that object can be observed via either variable. But changing the value of each variable to refer to a different list (or null) won't affect either the other variable or the object itself.
One thing which may be confusing you is what the value of a or b actually is. The value of a variable (or any other expression) in Java is never an object - it's always either a reference or a primitive value.
So an assignment operator, or passing an argument to a method, or anything like that will never copy the object - it will only ever copy the value of the expression (a reference or a primitive value).
Once you understand this, Java starts to make a lot more sense...
Variables like your a and b are called references. They refer to objects. The objects are floating around somewhere else (they are not stored "inside" the variables). When you say a=b you make a refer to whatever b refers to. In your case that makes no difference, because both already refer to null (i.e. to no object at all).
When you assign a new object to a that makes no difference to what b refers to.
Because you've redefined a. When you say:
a=new ArrayList();
You break the existing relationship between a and b.
Simply put. The variables refers to the object the other variable refers to in the moment it is set and not to the variable itself.
ArrayList a=null, b=null; // Both *a* and *b* refers to null
a=b; // Set *a* to refer to what *b* refers to (in this case null)
a=new ArrayList(); // Set *a* to refer to a new arraylist. *b* still refers to null.
Please advice why primitives being used as method's parameters do a copy of its value while objects are used as is?
In Java, all arguments are passed by value - but in the case of reference types (i.e. everything other than a primitive) the value of a variable isn't the object itself - it's a reference to the object. Thus that reference is copied into the method's parameter, so it refers to the same object.
Note that this doesn't just apply to method calls:
StringBuilder x = new StringBuilder();
StringBuilder y = x; // Copy the value of x, which is a *reference*
y.append("Hello");
System.out.println(x); // Prints "Hello"
Here, x and y refer to the same object, even though they're separate variables. Thus when the contents of that object is changed via the append call through the y variable, the change is visible via the x variable too.
I think of it as being a bit like giving someone the address of your house: if I give two people my home address, and one of them paints the door red, then when the second person visits the house, they'll see the red door too. I'm not giving them my house itself, I'm giving them a way of getting to my house.
There are many, many articles about this - although unfortunately some will claim that objects are passed by reference in Java. They're not - the references are passed by value, as I said above. Scott Stanchfield has a good article about this, amongst many others.
To expand on what Jon Skeet said, primitive types are usually quite small - a double is 8 bytes. Objects, on the other hand, can be HUGE, and so passing a reference to them saves time and stack space versus copying the whole thing. Plus this allows you to modify the contents of the Object.
That's what it looks like but is not. Java is always pass by value.
When you declare something like this:
Date aDate = new Date();
The variable aDate is not really an object, but an object reference. When you pass that object reference to another method, a "copy" of that reference is passed ( just like with primitives a copy of the value is passed )
Now, since those two copies "reference" the same underlaying object, you see that sending a message on one of them affects the other, but if you change the reference to assign a new one, the other doesn't change.
For instance:
class Some {
int data = 0;
}
class Other {
void doSomething( Some o ) {
o.data = 10;
}
void change( Some a ) {
a = new Some();
a.data = 1024;
}
}
class Main {
public static void main( String [] args ) {
// create an object and get its object reference
Some original = new Some();
System.out.println( original.data ); // prints 0
// now pass it to a method from the class "Other"
Other o = new Other();
other.doSomething( original );
System.out.println( original.data ); // prints 10, because data was changed in "doSomething"
// To probe that the reference is not passed, but a copy of it
// invoke the "change" method.
other.change( original );
System.out.println( original.data ); // remains 10, instead of 1024.
// the value 1024 was changed in the new reference, and the one passed along
// didn't change. It still refers to the original object.
}
}
I hope this helps