This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
Ok so if primitive data types in java are passed into methods, they are treated as pass by value. And if object data types are passed into methods, they are treated as pass by reference right? So in this code:
//Class 1
public void passByValue(int x){
x = 0;
}
public void passByReference(Integer y){
y= 40;
}
//MainClass(contains main method)
int primitiveType = 50;
Integer wholeInteger = 100;
Class1 a = new Class1();
a.passByValue(primitiveType);
a.passByReference(wholeInteger);
System.out.println(primitiveType);
System.out.println(wholeInteger);
This should result in primitiveType being equal to 50(variable hasnt changed). I understand that, however the Integer object is also not changed... So how does this work? Thanks!
Object references are passed by value too. It is the reference that is passed and not the object. You confuse pass-by-reference of the object with pass-by-value of the reference.
In A x = new A() the symbol x is a reference to an object of type A.
If x is a reference and f(A a) { a = null; } is a method then f(x) will not set x to null. Hence, the reference was passed by value.
The reason behind this (and your confusion) is that - to some extend - the phrase "the object is passed by..." is already wrong. Because correctly we have to say "the object reference is passed by...". If A is a class then A a; means that a is a reference to an object of class A. If that is clear, it becomes clear why we have a pass-by-value.
First of all there is no pass by reference in java when you pass an object then it's also pass by value...
secondly, like String class , the wrapper class Integer is also immutable...
when you write Integer y= 40 ; then new Object new Integer(40); is being created by autoboxing feature java supports ..
That's why .... there is no change in value of wholeInteger you passed..
Related
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
So I thought Java was pass by value but why does the following code:
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
phase1(numbers);
for (Integer number: numbers) {
System.out.println("number = " + number);
}
}
static void phase1(List<Integer> numbers) {
numbers.remove(0);
}
Print the following?
number = 2
number = 3
So I thought Java was pass by value
It is.
...but why does the following code...print the following?
Because the value passed for reference types is the reference, not a copy of the object.
"Pass by reference" refers to a completely different thing, passing a reference to the variable. Java doesn't have that.
If Java had pass-by-reference, then this change to your method:
static void phase1(List<Integer> &numbers) {
// Pass-by-reference indicator --^--- that Java doesn't actually have
numbers = new ArrayList<Integer>()
}
...would make your code print no numbers at all. But it doesn't, so it doesn't.
Think of the object reference as an int or long that uniquely identifies the object elsewhere in memory. (Which is basically what it is.) Just as a = b with ints copies b's value into a, so a = b copies b's value into a even when the value is an object reference. The value being copied is the reference, not the object it refers to.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
static void number(int x){
x=42;
}
public static void main(String[] args) {
int x =17;
number(x);
System.out.println(x);
why is the value printed out still 17 and not 42? Thanks!
The line
number(x);
passes the value of x into number. Nothing that links back to x is passed at all. Inside number, the x argument you've declared is not in any way linked to the x variable in main; it just receives the value that you passed into number. Assigning to the argument (x = 42) just changes the value of the argument, not the variable in main.
This is called pass-by-value, meaning that whenever you pass a variable into a method, the value of that variable is passed, not anything about the variable itself. Exactly the same thing happens here:
x = 17;
y = x;
y = 42;
System.out.println(x); // 17
System.out.println(y); // 42
y = x just takes the value of x and puts it in y. There's no ongoing link between x and y.
So how would you change it? The usual approach is have number return a new value:
int number(int val) {
return val * 2;
}
Then in main:
x = 17;
x = number(x);
System.out.println(x); // 43
Sometimes, people get confused by pass-by-value when it involves object references. Variables directly contain primitives like int, but they don't directly contain objects; they contain object references. So consider:
List<String> l1 = new LinkedList<String>();
Now, l1 contains a value that is a reference to the linked list object. Now suppose we do this:
List<String> l2 = l1;
What happened there? Do we have one list, or two?
The answer is, of course, one: The value we copied from l1 to l2 is the reference to the list, which exists elsewhere in memory.
Key points in summary:
When you pass a "variable" into a method, it's the value of the variable that gets passed (always — Java is purely pass-by-value [some other languages have something called pass-by-reference, where a reference to the variable is passed, but Java doesn't have that)
The same thing happens when you assign a variable to another variable
Object references are values that tell the JVM where the object is in memory
Java is pass by value So when you passes x which is defined in main() to number() method ,only the value is copied to function parameter x and no address is passed unlike C pointers.So the value you get is 17 because it is not changed.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
One of the most popular answers to one of the most popular questions in Java here reads:
Java is always pass-by-value. The difficult thing to understand is that Java passes objects as references and those references are passed by value.
So what does "Java passes objects as references and those references are passed by value." mean?
Does it mean that:
The memory location to which the original variable points is copied as the value of the new temporary variable? (if this is the case, all the changes made inside the function will be reflected in the original, right?)
If not, what does it mean?
Think of objects references as "pointers to a value"
When you pass a value into a method, you pass the pointer in, therefore the two pointers (the one in the method, and the one you passed in) point to the same thing.
Consider this
public static void main(String[] args){
Foo cl = new Foo();
cl.z= 100;
method(cl);
System.out.println(cl.z);
}
private static void method(Foo bar){
bar.z=10;
}
Before you call method, cl.z would be 100, but after you pass it in, it would be equal to 10.
What is not correct is this:
public static void main(String[] args){
Foo cl = new Foo();
cl.z= 100;
method(cl);
System.out.println(cl.z);
}
private static void method(Foo bar){
bar = new Foo();
bar.z=10000;
}
This would NOT print out 10000, because you cannot assign the pointer to reference a different object
When we say Java is pass-by-value, it means that if you modify a parameter inside a method, it has no effect on the caller. For example:
public void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
All this does is swap local copies of the parameters. Thus, if you say
int x = something;
int y = somethingElse;
swap(x, y);
x and y would not change.
The same is true for references:
public void someOperation(MyClass a) {
a = ...something...;
}
Inside your method, a is a copy of whatever reference you pass in; if you reassign a to something else in the method, it doesn't affect any variable in the caller.
MyClass x = ...;
someOperation(x);
x does not change, even though you've changed the parameter a inside the method.
Note that this means that x itself will not change. It will not point to a different MyClass instance, even though a in the method was changed to refer to a different MyClass instance. However, even though the reference does not changed, the object that the reference refers to could be changed by the method.
It means the reference (a memory pointer to the object) is passed by value. If you modify the object, you modify the reference to the object; thus the change will be seen across your application. If you modify the pointer, then your only change it for the scope of your method.
void method(Foo f) {
f.bar = 10; // Seen accross your application.
f = new Foo(); // Modifying your pointer. This does not change the previous object.
}
Yes, Java is always pass-by-value, with both reference types and primitive types. But that doesn't mean that changes within functions always affect the object passed in as an argument.
If a primitive type is passed in, then there is no reference passed, it's by pure value, and any values in the calling scope will not change.
If a reference type is passed in, whether or not a function can modify it depends upon if the type is mutable (the object can be modified) or immutable (the object itself cannot be modified, a new object must be created for all modifications).
If it is mutable, like StringBuilder or HashMap<String, String>, then the function is able to modify it and changes within the function will still be in place after the function call returns. However, note that changing what a reference type points to is not modifying it, in that case, you are only changing what the reference type points to, not the original object referenced by an argument, but doing an operation like strbuilder.append("xyz") is.
If it is immutable, like String or Integer then all modifications within the function will create a new object and the changes will not be in place after the function call returns.
This question already has an answer here:
Java method doesn't change parameter objects [duplicate]
(1 answer)
Closed 8 years ago.
Ok. I'm completely aware that all values in Java are passed by value. But this example does not behave as I expected:
public class Test {
private static void changeInteger(Integer x) {
x = 5;
}
public static void main(String[] args) {
Integer x = 0;
changeInteger(x);
System.out.println(x);
}
}
Since I'm passing wrapper class to the changeInteger Method, I'm passing its address, so, after executing function that should affect my x variable and set it to 5. But eclipse says that output is still 0. What did I understand wrong?
Consider this example:
class Wrapper {
int n;
public Wrapper(int k) { n = k; }
public String toString() { return ""+n;}
public static Wrapper valueOf(int k) { return new Wrapper(k); }
}
Now let us replace Integer in your code with the Wrapper class above:
private static void changeInteger(Wrapper x) {
x = Wapper.valueOf(5);
}
public static void main(String[] args) {
Wrapper x = Wrapper.valueOf(0);
changeInteger(x);
System.out.println(x);
}
Since you mentioned that you know about passing by value, I hope that it is clear why this code does what it does.
Now let's go back to your code. Under the hood, it is exactly the same code. The only difference is that you do not call Wrapper.valueOf: the compiler does it for you through autoboxing. Once you realize that this is what is going on, the issue should be clear to you.
ByteCode of changeInteger() to show that Integer.valueOf() is called :
private static void changeInteger(java.lang.Integer);
Code:
Stack=1, Locals=1, Args_size=1
0: iconst_5
1: invokestatic #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In
teger;
.... // some other code
With x = 5; you assign a new value to x inside changeInteger(). You are not changing the value of the current Integer object.
The value of x outside the method is not affected.
You get puzzled by the autoboxing function of java. You cannot assign a primitive value to an objec. When you call x=5 it creates a new Integer object with 5 value and assignes its reference to x. But this affects only the parameter in the scope of changeIngeger, the original object with 0 and the reference of x in main scope are untouched.
Your problem is the fact that Java is pass-by-value not by-reference so the x in the method is not the same x of main. The fact that Integer is an immutable class, here doesn't change anything.
All Java parameters are passed by value. For all non-primitive types, the value contains a reference to the object that's passed.
For your piece of code, the Integer object is stored at location A in memory. Another location B in memory represents the main's variable x and stores a value A.
For the changeInteger call, a new location C is created and a value in B (which is A) gets copied to it. This is the local x of the changeInteger function.
With the assigning, you create a new variable stored at D and its location is assigned to C. Then you return from the method.
You can see that A and B isn't modified anywhere and thus the value remains unchanged.
Keeping as simple as it is, All Java Wrapper classes are Immutable. So you cannot seeing the change.
If you want to see the change, just return from method (not main) and assign it back.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
while learning C language I have learned that when you pass a variable to a function. you are not passing the variable itself you are passing a copy of it so the actual varible's value will not change unless the function returns a value and you assign that value to the variable.
but I just executed this program and this happened when I passed "Newobj" object to a "changer" function and then change the values of the variables and then print the new variables values it is working. It should not happen right? because I am sending the copy of "Newobj" to "copyobj". explain please I am confused.
Note: Explain in detail please. My brain is slow. I know the concepts of c and few concepts of c++;
here is my code:
public class PassObjects {
int regno;
String name;
double per;
PassObjects(int a,String s,double p){
regno=a;
name=s;
per=p;
}
PassObjects changer (PassObjects copyobj){
copyobj.regno=797;
copyobj.name="Srimanth";
copyobj.per=70.9;
return copyobj;
}
public static void main(String[] args){
PassObjects Newobj= new PassObjects(86,"srimanth",85.4);
System.out.println("The original values of Instance variables are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
Newobj.changer(Newobj);
System.out.println("The changeed values of Newobj are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
}
}
output is here:
The original values of Instance variables are 86 srimanth 85.4
The changeed values of Newobj are 797 Srimanth 70.9
What you are doing is passing a pointer to an object. You are effectively modifying the PassObjects object.
There is a difference between a reference type and a value type. For example, a function that takes an integer and modifies it will indeed receive a copy of that integer.
public void add(int x)
{
x = x + 1;
}
However, an array of ints is also a reference type.
When you call this function using the following code:
int x = 5;
add(x);
// X will still have a value of 5.
This is because x is a value-type. You call the function and pass in a copy of the integer.
However, when you create an object, you do not pass a copy of the entire object. See code below.
public void ChangeName(SomeObject x, String newname)
{
x.name = newname;
}
SomeObject x = new SomeObject("thename");
ChangeNameTo(x, "newname"); // As the comment below pointed out, you don't even have to reassign.
//x.name will have the value "newname" now.
You can read more here and here.
Java does manipulate objects by reference, and all object variables are references.
That means u only created a new reference to the same object and when u changed the values then it gets changed in actual object.