Java reference-type in parameter - java

Why doesn't this change the initial object:
public class Foo
{
Bar item = new Item(5);
public changeBar(Bar test){
test = new Item(4);
}
public run(){
changeBar(item);
}
}
In this case item doesn't get changed. How is this possible? I mean, you're passing the reference as parameter in the method, so I'd say assigning a new value to it, means the initial item would also be changed.
Can someone explain to me how this works.
=======================================
however, my question is the following:
the following does work right?
public changeBar2(Bar test){
test.parameter = "newValue";
}
I don't see how that's different.

Consider a thought experiment:
changeBar(null);
Would your code above change the value of null?
The answer to your question is that although your Bar object is passed "by reference", this is different from passing the reference itself by value. In Java, all parameters are passed by value, even when they are themselves references to other objects.

public changeBar(Bar test){
test = new Item(4);
}
changeBar(item);
Here the value in item in copied to test. So as of now, both item, test are pointing to same object(s). Inside the method, test is pointing to a different location which doesn't affect the item. You are passing by value and not by reference.
public changeBar2(Bar test){
test.parameter = "newValue";
}
The above modifies the object that is passed because both the test and item are referring to the same object.
So, test can totally either point to a new object or modify the object was earlier referring to. Both are different and are valid.

Parameters in Java are ALWAYS passed-by-value.
At the beginnning of function changeBar() test is a reference to item, but then you overwrite it with a reference to a newly created item. You therefore only overwrite the local variable with a different reference, but don't change the referenced by object.

test in changeBar is basically as pointer. So when you assign it, you are changing the pointer.
Here is an article: http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

You are giving the method the reference to this object, that is, its address so to speak. So this address is stocked in a variable named test.
Then your method erases what is written in the test variable, and writes instead the address of a new Item object it created. Nothing here changes anything to the initial Item object, nor to the references to it that are outside the method's scope.
I guess I am pretty approximative here and I will be glad to get corrected.

Related

How to properly copy objects [duplicate]

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.

what exactly happen in jvm when i create an object in java?

To my understanding if i am writing
Car a3=new Car()
This statement will create a handle named a3 in jvm stack with all its properties in JVM heap.
IF this is correct i am wondering how call by value works.
So, if i create a method checkMethod(Car c) and call it by saying checkMethod(a3);
suppose our car is
public class Car{
int a=0;
public int getpar(){
return a;
}
}
in checkMethod i try to access a using a3.a = 5; so i changed the value of a3.a
it will show me in the calling class as well as it was pointing to the same fields that jvm created in the heap.
But when i do a3= null; in the calling method and go back again in the method from which i was calling
checkMethod(a3) and try to see this object it is not null?
Why it behaved differently as compared to property of object that is a???
checkMethod(a3);
Pass a copy of a value which is a reference to object instance of Car
Inside method...
a3.a = 5
Using a3, modify object instance of Car which is identified by a3 ( which is a copy of original a3).
a3 = null
Set the reference to null ( copy)
When this happens, only the copy you passed to your method will point to null. But the original a3 still points to your object instance of Car.
Why it behaved differently as compared to property of object that is a?
Because Java is (pure) call by value. You cannot manipulate the value of the parameter within the callee context. You always gets a local copy in the calling context.
On method calls, Java passes a copy of the reference.
So when setting a3 to null, it only set its copy of the reference to null and the other copies that are stored else where.
The whole trick is this: Java passes references by value :)

java: Passing an object

I've been reading many posts about this, all are full of answers that tend to counter the answer before it and they all seem to be by high ranked people so im very confused and would just like to know if this works:
public class Object{
private int someNumber = 5;
public void setSomeNumber(int newNumber){someNumber = newNumber;}
}
public class Main {
Object myObject = new Object();
public static void main(String[] args){
changeNumber(myObject);
}
void changeNumber(Object obj)
{
obj.setSomeNumber(10);
}
}
Would this change myObject.someNumber to 10?
My understanding is that obj is pointing to the same place in memory as myObject so calling its method useing obj is the same as calling it with myObject because obj is not just a copy of myObject?
I thought it was clear to me till i started reading threads on here about it lol
Edit: Thanks for correcting code, i just wrote it out in here as a example, didnt see the mistakes
Thanks guys. Also i was confused by people saying pass by value so i wasnt sure if it was passing the address in memory or not because to me thats passing a refrence so it became unclear to me.
You are correct. changeNumber() would change the someNumber variable of the object passed to it. You are passing a reference to the object itself, not a copy.
Although this code won't compile (you can't use Object, and can't access from static method non static data field), but I've got your question.
Basically you're right, and this is why:
In Java when you pass parameters into the method, they're passed by reference, but the reference itself is passed by value.
This is done for optimization reasons I believe.
So in fact, another reference is produces that points to the same Object in memory.
If you take a look on these references by themselves they're different, but they both point on the same object. So when you change the internal state of the object from within 'changeNumber' method, its goes to the object that reference 'obj' refers to and changes it.
The only exception is primitives - they aren't passed by reference, instead they're passed by value as you probably have learnt in other languages.
Once you get aware of what exactly goes on when you call methods and pass parameters to it this will stop confusing you :)
Hope this helps
You are right, java does manipulate objects by reference, and all object variables are references, and doesn't pass method arguments by reference but by value.
Take a look at this article and see the difference in behaviour between objects and method arguments in the examples provided.

Recursive pass in object by reference? JAVA

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.

How to pass mutable objects by value to java

Is there any way that I can pass mutable Objects by value to a function in java?
What I actually want is to pass an object to a method, do some operations on it (change it) and again call that method with that old object only(not the changed value).
here is some sample:
{ MyObj obj = new MyObj(); obj.setName("name");
append(obj);
System.out.println(obj.name);
prepend(obj);
System.out.println(obj.name);
}
void append(MyObj obj){ obj.name+="1"; }
void prepend(MyObj obj){ String a = "1"; obj.name=a+obj.name; }
At the end of this code, I want output as:
name1
1name
Objects themselves aren't passed at all in Java. Ever.
But everything is passed by value - where the only things that can be passed are primitive values and references.
It's not quite clear what you're trying to do - is the idea that you'd like to have a method with (say) a StringBuilder parameter, but without any changes made to the object from within the method being visible to the caller? If so, you basically need to clone the object yourself.
Unfortunately, no. Java never passes Objects by value, it passes the reference of the object by value.
Explanation from here:
What's really happening is that
objects are always held by reference
in java -- never by value -- and the
references are, indeed, being passed
by value.
Why do you need to do this? If you don't change the object, then it doesn't matter. If you do change the object, and don't want to affect the caller's object, then just make a copy locally. But I would guess that at least 90% of the time people think they need to do that, they really don't.
Show some code. What are you really trying to do?
AFAIK immutable/mutable is not related with passing by value/reference. Strings are passed by reference, not value. What makes string immutable is design of string class itself.
Perhaps you may explain a bit more what you looking for.

Categories

Resources