This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 4 years ago.
If I instantiate an object and pass it to an function, in this function I assign this object to null.
It seems when return from the function, the object still there.
I just want to know when I assign null, what happens.
You can never assign to an object. All you ever have are primitives and references. A reference is either null or a pointer to an object of suitable class.
Java arguments are passed by value. Your called method got a copy of a reference. It made that reference null. The calling method has its own reference which was unaffected by any assignments to the passed copy. That reference still points to the object.
Arguments to methods in Java are 'pass-by-value', which means you are passing a copy of the object reference into the method. Assigning this reference a value of null will change its value within the method call, but does nothing to the reference outside the method, since its a copy. Illustrated with code:
void doSomething(final String input) {
input = null;
System.out.println("Input is: " + input); // prints null
return;
}
final String name = "Bob";
doSomething(name);
System.out.println("Name is: " + name); // prints 'Bob'
when you instantiate an object and pass it to a function, and inside the function you reassign that to null or whatever, at the calling side it is not reflected as arguments are pass by value (copy of reference in case of objects), at calling side it'll still point to the old object. If you want to restrict reassigning in a method, you can use final keyword in method parameter
When you pass the object reference to a function(Java always call it method),in the method scope,a new reference is created on stack memory,but they point to the same object in heap memory.So if you assign null to the new reference,Only this reference's link to that object is break,It does not affect the prevous one.
Related
This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 2 years ago.
I was working on this bug in my application and saw something very weird:
selectedService = dataResponse.getServices().get(position);
selectedService.setPrice(3000);
dataResponse.getServices().get(position).getPrice(); // Returns 3000 which should be 0
Shouldn't the get method copy the object into selectedService? If not how to copy it?
No, it shouldn't.
Java is always pass-by-value, but that value itself is a reference. So if you call a method which alters data of that particular object, it is reflected to all methods retrieving data from that particular object.
A possible solution to this problem is to make immutable types. There are classes which already implement this, for instance, all classes from the java.time package are immutable. All 'setters' of those classes return a fresh copy of the instance, with the specified value set. An example may be LocalDate::plusDays.
Here is a little example of the difference between pass-by-value and pass-by-reference.
Take a look at this code.
void main() {
Dog myLittleDog = new Dog("Brutus");
change(myLittleDog);
System.out.println(myLittleDog.getName());
}
void change(Dog aDog) {
aDog = new Dog("Jack");
}
What happens here? We pass our dog named "Brutus" to the change method. Within this method, we replace Brutus with a new Dog named "Jack". If we print the name of myLittleDog, what will be his name? Will it be "Jack"?
The answer is no. The value of the reference to the dog is copied, and is available within the change method under the name aDog. Both myLittleDog and aDog are referring to the same actual dog object in memory. But now the change method reassigns aDog with a new object. At this moment, the variables myLittleDog and aDog both refer to distinct objects. Once the change method exits, the variable aDog is unreachable and Jack is garbage collected. myLittleDog is still called "Brutus".
Conversely, this wouldn't be the case if Java was pass-by-reference. Then reassignment of aDog would also mean reassignment of myLittleDog.
See also: What's the difference between passing by reference vs. passing by value?
But then why is my selectedService still mutated?
Although values of references are copied when they are passed to methods, doesn't that mean that objects cannot change (that is, be modified). Suppose I give you a copy of my house key. You access my house and move the couch to the kitchen. Then if I enter my house, I will see that the couch has been moved. The reference value is copied, but everyone accessing the referenced object (the house), will see modifications to it.
selectedService here is a reference variable which points to whatever object you assign to it. While assigning dataResponse.getServices().get(position) to selectedService it appears as if you're assigning an object to it, however, what you're actually assigning is the reference to the original object.
As quoted on https://www.geeksforgeeks.org/clone-method-in-java-2/
Unlike C++, in Java, if we use assignment operator then it will create a copy of reference variable and not the object
To create a copy of the object
Use the clone() method to create a copy of the object as in
selectedService = (SelectedServiceClass) dataResponse.getServices().get(position).clone();
This question already has answers here:
How do I copy an object in Java?
(23 answers)
Closed 8 years ago.
This might have been asked already but since I am not so sure how to phrase it I could not find it.
Essentially
Suppose we have the class a, (see code below), and we want to copy an instance of it, a1, to another instance a2.
So, in my main I would have a1.copy(a2)
I know that using copy2 method this will work. However copy1 will not. I just would like to clarify why this is. Is it because the parameter is just a "copy" of the object, so the object itself (a2) is not altered.
class a {
private int val;
public class(int val){
this.val = val;
}
public void copy1(a obj){
obj = this;
}
public void copy2(a obj) {
obj.val = this.val;
}
}
The key to understand your problem is that Java's method call is always pass-by-value, not by reference.
When you call a.copy1(b), Java copies a value of b's reference(say it is called b_copy, please note that b_copy points to the same memory location as b), and then pass b_copy to the method copy1.
And in your method of copy1, Java only changes the reference of b_copy.
public void copy1(b_copy){
b_copy=a;
}
So now :
b_copy: b_copy=a;
b: b does not change at all;
When the method ends,b_copy dies. So nothing changes on b!
While a.copy2(b) manipulates on the object itself, but it still copies a new value of b(say b_copy again) and pass into copy2
public void copy2(b_copy){
b_copy.val = a.val;
}
Since b_copy points to the same memory of b, so when you do changes on b_copy.val, you also does the same on b.val itself. That's the reason why b changes.
So now :
b_copy: b_copy, but b_copy's val changes
b: b's val also changes, since b_copy is points to the b's memory location;
And then when method ends, b_copy dies, and b has changed!
You may find more discussion on Is Java "pass-by-reference" or "pass-by-value"?
And you may also need How do I copy an object in Java?
When you call the method copy1(), the parameter is a copy of the reference of the object a obj. When you set it to this (obj = this;) the copy of the reference of the object is replaced by the current object, but the original object and the reference to the object at the place you are calling the copy1() method stays the same. You just change the copy of the reference of the object.
When you call the method copy2(), no reference work is done there, and you are doing one by one matching of the variables (properties of the objects) and there is no copy of reference work there. You are changing the object itself. In this case, this.val = obj.val; would also work.
For more understanding, check this topic and check how other languages like C or C++ handle parameter passing issue.
I think you might want to look into how parameters are passed in Java.
For primitive variables, they are passed by value. If I recall correctly, this means that a temporary value is passed and any changes to the variable in the function update only the temporary variable.
However, objects are passed by reference. This means that instead of the entire object, essentially a pointer to where the object is in memory is passed.
What this means is that updating an object's variables produces lasting effects on that object. Additionally, if you set one object equal to another object, you're really just setting the memory references to be the same (a byproduct of this is that the values of the variables in the objects are then linked).
This explains why the first function fails to do what you want (you're setting the memory locations to be the same). And the second succeeds (you're performing a deep copy into a new memory address).
Your reasoning is correct. When you pass an object to a method (as you do in copy1), all you are doing is creating another reference to the same object. If you override this reference, as copy1 does, it just means that that reference now points to a different object - it does not, and can not, change the original object.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
I have the following code:
public class PassReferenceByValue {
static void modify(String m)
{
m = "Else";
}
public static void main(String [] arg)
{
String actual = "Something";
modify(actual);
System.out.println(actual);
}
}
It will print Something.
I get that Java doesn't pass objects at all. Instead, it creates copy of the reference passed. If i understood correctly, when I call modify(actual) Java creates another reference to the same object. So, now we have two references that reference to the object actual. Now, through the second reference, we modify the object and the object should change. The object actual should change, because through the copied reference we have the same access to the object.
Can somebody explain me where I fail to understand the concept of passing references by value?
static void modify(String m)
{
m = "Else";
System.out.println(m);
}
If you do this m will print Else, it is only the local variable m what is getting assigned to a new value. value of actual in the main method is not getting changed here.
All "variables" in Java are references to address in a memory when the object resides.
So you have:
actual -> String("Something")
after method invocation you have
actual -> String("Something")
and
m -> String("Something")
You are just changing m -> String("Else")
bot not actual -> String("Something")
Where String("...") notation means object String with value "...".
Check this
Java's pass by value and pass by reference is nicely explained
Strings are immutable, but that's a different discussion
You are not modifying the "object" pointed by String reference actual. In the method modify() you are just overwriting the reference to point to a new String object called "Else". Now this doesn't make any "effect" to the object pointed by actual. Hence when you print actual, it still remains the same
Why I am trying to make point 1 is, say your modify method was like below
public void modify(String s) {
s.replaceAll("Some", "Many");
}
Still the actual would have printed "Something" because of String's immutable behavior.
You're changing m which is a local variable only visible within modify() referencing an object. You're creating a new String object with the value "Else" and making m point towards it.
When you then come out of modify() and print actual, it is still a reference to the String object containing the text "Something".
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is Java “pass-by-reference”?
Pass by value or Pass by reference in Java?
When we pass the arguments to a method inside a java class. Are the parameters passed in By VALUE or BY REFERENCE as default?
There can be two possibilities,
1. if we pass arguments to a method from another method within the same class.
2. if we pass arguments to a method from another class.
Secondly, if i want to pass values by reference (in case default attribute of java is By Value) then what should i do?
Whatever be the case.. Java is PASS BY VALUE and even references are passed by value
and to get more examples here are few interesting links to read out
http://www.javaworld.com/javaqa/2000-05/03-qa-0526-pass.html
How to do the equivalent of pass by reference for primitives in Java Pass by value or Pass by reference in Java?
I am pretty sure that Java is all pass by value. C/C++ is in to passing by reference. As far as working around passing by reference it is quite easy. As with with C, Java has return type methods. You simply place the variable to the left of the assignment ( = ) operator to call of a method that returns what its new value should be. Plus a few other ways.
String name = "Jon Doe";
name = getName();
String getName()
{
//code to get name goes here.
}
So I have an algorithm that forces me to pass in an object as a parameter recursively and on different depths of the recursion it sets the values of the object. The problem is Java isn't allowing me to do this because they pass in by value or something else that is just messing me up. How can you make sure that the object passed in retains the value set?
You never pass an object as an argument in Java. You either pass a reference or a primitive value. The argument is always passed by value. Java doesn't have pass-by-reference at all.
If you're passing in a reference to an object, and you want to make sure the code you call doesn't change the data within that object, your options are:
Create a copy and pass in a reference to that instead
Make your type immutable in the first place.
EDIT: Just to make it clear, if you have:
Foo f = new Foo();
then the value of f is not a Foo object. It's a reference to a Foo object. If you now call:
doSomething(f);
then the value of f is copied as the original value of the parameter within doSomething. That behaviour is basically the definition of pass-by-value. There's nothing doSomething can to do change the value of f - it will still refer to the same object afterwards. The data within that object may have changed, but it won't be a different object.
In a real-world analogy: if I give you a copy of my address, you can go and paint the front door, but you can't change where I live.
As Jon states, all non-primitives are passed by passing a copy of the reference. You don't have a choice. So your recursive method should be able to update the object if it is mutable. HOWEVER, you can't reassign a reference and expect it to propagate back up the call stack. And remember that Strings are not mutable.
In other words, if you do the following, you have not changed the object that was passed:
void myMethod(Object o){
o = new Object();
}
The above changes the local reference to o but does not change the caller's reference to o. If you need to do something like this you would need to return o.