This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
public class Foo {
public static void change(int[] arr){
arr = null;
}
public static void change2(int[] arr){
arr[0] = 99;
}
public static void main (String[] args){
int[] arr = {1,2,3,4,5};
change(arr);
System.out.println("it should null: "+Arrays.toString(arr));
change2(arr);
System.out.println("updated array : "+Arrays.toString(arr));
} }
CONSOLE OUTPUT
it should null: [1, 2, 3, 4, 5]
updated array: [99, 2, 3, 4, 5]
I need to get understanding about pass by reference as i passed int[ ] to first method i.e change() it does not null the array as per my understanding it should change to NULL as array references are pass by reference but if i pass array to second method i.e change2() it changed the value at specific index. It means that reference is being passed.
It is because the Array in java are objects, and the array reference variable is passed by value in public static void change(int[] arr){ , hence you cannot change the reference variable by doing:-
arr = null;
//or
arr=new int[10];
But you can change the object pointed by the copy of array reference variable (i.e arr passed to the method):-
arr[0]=1
This is not pass by reference. In Java everything is passed by value. What gets passed to the method is copy of the reference. Since this new reference is also pointing (referencing) the same object, you can manipulate the object using new reference.
But if you assign a different object to this new reference, it will not change which object is pointed (referenced) by the old reference. Old reference still points the same object, which it used to point. So no problem for old reference.
So the outputs are perfectly fine.
C# allows pass by ref. Though to mention this.
Related
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 3 years ago.
i was working on stacks when i came across a problem where i had to double the array. i used this code which did not work but it should have.
class ArrayDouble
{
public static void main(String []args)
{
int arr[] = new int[10];
sizeChange(arr);
for(int i=0;i<arr.length;i++)
System.out.print(arr[i]+ " ");
}
public static void sizeChange(int arr[])
{
arr[0]=1;
arr = new int[2*arr.length];
arr[1]=1;
}
}
from what i have seen, any changes that takes place in an array which has been passed as a parameter, the changes reflect back in the actual parameters right? So why doesn't the change in size of the array is reflected in the original parameter?
Also, arr[0] becomes 1 in the original array but arr[1] remains 0. why does that happen?
PS: the problem was solved when i changed the return type of sizeChange to int[] and passed arr of sizeChange and collected it into the Main arr. So i dont need the correction of the code, i just need the answer as to why this is happening.
Thank you in advanced.
Arrays are not a primitive type in Java, but they are not objects either ... "
In Java, the called method can update the contents of the array, and it can update its copy of the array reference, but it can't update the variable in the caller that holds the caller's array reference. Hence ... what Java is providing is NOT pass-by-reference.
Like all Java objects, arrays are passed by value ... but the value is the reference to the array. So, when you assign something to a cell of the array in the called method, you will be assigning to the same array object that the caller sees.
This is NOT pass-by-reference. Real pass-by-reference involves passing the address of a variable. With real pass-by-reference, the called method can assign to its local variable, and this causes the variable in the caller to be updated.
Detailed Explaination :
Arrays are in fact objects, so a reference is passed (the reference itself is passed by value, confused yet?). Quick example:
// assuming you allocated the list
public void addItem(Integer[] list, int item) {
list[1] = item;
}
You will see the changes to the list from the calling code. However you can't change the reference itself, since it's passed by value:
// assuming you allocated the list
public void changeArray(Integer[] list) {
list = null;
}
If you pass a non-null list, it won't be null by the time the method returns.
This question already has answers here:
Does initialized java array go onto stack or heap?
(2 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 5 years ago.
Is the following code safe in Java? My concern is due to the fact that in function f() variable arr is allocated on stack and as such is deallocated upon leaving the scope but is still referred to outside the scope.
public class Main {
public static class Array {
public final int[] arr;
public Array(int arr[]) {
this.arr = arr;
}
}
public static Array f() {
int arr[] = {1, 2, 3};
return new Array(arr);
}
public static void main(String[] args) {
Array a = f();
System.out.println(a.arr[0]);
System.out.println(a.arr[1]);
System.out.println(a.arr[2]);
}
}
In f you create variable arr which is an int array and then construct an Array object which ends up having a pointer to that same primitive int array.
Function f then ends returning the Array object - the variable arr goes out of scope but the memory location it points to is still referenced by the Array object being returned so the memory location cannot be garbage collected. The return value is then assigned to variable a of your main method meaning that the memory that arr originally pointed to still cannot be garbage collected until the main method ends. This is shown by the fact that the values of what was originally called arr are output as part of the main function
Short answer, yes this is safe to do. Memory is garbage collected when nothing is left pointing to it / when it is no longer referenced
It's safe because java uses references to track it. Even when arr goes out of scope in f, data is still referenced by a. Garbage collector will not clean it in the time it takes for the return value to be assigned, either.
On a side note, try to avoid using the same name both as local variable and field.
First of all, I understand what's so called passing by value in Java.
Also I understand, when you pass an object or an array, it is the array's address that is passed into the method. So modifying the array variable inside the method will affect the outside array variable.
For example,
private void change(int[] a) {
a[0] = 1234;
}
public static void main(String[] args) {
int[] a = new int[2]{1,2};
change(a);
System.out.println(a[0]);
}
The output will be 1234, because the a inside change is actually the array outside.
What I don't understand is the following code:
private void change(int[] a) {
a = new int[3]{1234, 4, 5};
}
public static void main(String[] args) {
int[] a = new int[2]{1,2};
change(a);
System.out.println(a[0]);
}
Why the output is 1, not 1234?
The inside a was the same thing as outside a, right? I also modify the inside a just like the example above did, why two different output?
This is not the same. In your second example, you are changing the local reference a to refer to a completely new array, not changing the existing array. But this does not change the a in main to refer to the new array; it still refers to the old array, so 1 is printed.
If you wanted to re-assign a completely new array to the a in main using a method, then return the new array from change and assign that to a in main.
Let's inspect your function:
private void change(int[] a) {
a = new int[3]{1234, 4, 5};
}
As you stated in your question, a is a reference to an array. If you use it to modify the array (e.g., a[0]=1234), you will be changing the same array that was passed in to the function.
However, if you change the reference itself, a will no longer be pointing to the original array, and changes to it will not affect the original.
This is exactly because the reference is passed by value. We'll represent object pointers with 5-digit numbers like 12345. The process is as follows:
We create an int[]{1,2}, at memory location, say 10000. We assign a the value 10000. a is on the stack frame corresponding to main.
We pass the value 10000 to change.
change executes:
change creates a new array at location 20000 and sets the value of a on its stack frame to 20000. This does not affect the main stack frame.
change returns (void).
We deference the untouched pointer to the original array in order to print the zeroth element, 1.
Note that by the time change returns, we have no live references left to {1234, 4, 5}.
In Java all variables are references to objects.
When you pass a variable into an array, you pass the reference to the object. If you modify the object then the calling method - which also has a variable that refers to the same object - sees the change.
When you write "a = new int..." you are changing the value of the variable a to point to a different object. It is no longer referring to the same object as the one in the method that called it. So the calling method and the called method see different things.
When you pass a parameter by value, it basically means that it's copied from a method's point of view. So, you have a reference a to an array, and when you pass it to some method, inside that method you have another reference, also named a to the same array. Now, when you assign a new value to that reference (a = new int[]...) you are only modifying the local a variable to point to a new array.
The answer has as much to do with passing by reference or value as it does with which variables are in scope when you attempt to make the change.
When you pass "a," or any variable to a method, you pass the value of that variable - in other words a copy of what it represents- and not the actual variable itself. For example:
public static void main(String[] args){
int a = 3;
addTwo(a);
System.out.println(a);
}
private void addTwo(int a){
a += 2;
}
In the above example the value 3 is passed to addTwo. The variable "a" in the main method is outside of its scope (i.e. it is localized to the main method) so the addTwo method acts only on the copy of "a," the value 3, and not the variable. The variable "a" remains unchanged. When the method completes the value of a is discarded and the original "a" in the main method remains unchanged.
This is the same thing that is happening in your case. It does not matter that you use the same name for two variables. The variable in your main method will not be changed.
I am trying to understand the difference between Object with primitive variables when using them as parameters in a method.
There are some examples using reference variables:
public class Test1 {
public static void main(String[] args) {
int[] value = {1};
modify(value);
System.out.println(value[0]);
}
public static void modify(int[] v) {
v[0] = 5;
}
}
result: 5
public class Test2 {
public static void main(String agrs[]) {
Integer j = new Integer(1);
refer(j);
System.out.println(j.intValue());
}
public static void refer(Integer i) {
i = new Integer(2);
System.out.println(i.intValue());
}
}
result: 2 | 1
So what is different in here?
In java array is primitive type.and Integer is Object type.
For primitives it is pass by value the actual value (e.g. 3)
For Objects you pass by value the reference to the object.
In first example,
you are changing value in array.
while in other example ,
you are changing reference of i to other memory location where object value is 2.
when returning back to main function, as you are not returning value. its reference scope limited to "refer" method only.
Recall that the array references are passed by value. The array itself is an object, and that's not passed at all (That means that if you pass an array as an argument, your'e actually passing its memory address location).
In modify() method, you're assigning 5 to the first place in the array, hence, changing the array's value. So when you print the result, you get: 5 because the value has been changed.
In the second case, you're creating a new Object of type Integer locally. i will have the same value when you exit the method refer(). Inside it you print 2, then you print i, which is 1 and hence change doesn't reflect.
v[0] = 5, is like saying Get 0th element of current v's reference and make it 5.
i = new Integer(2), is like saying change i to 2's Integer object reference
In one case you are changing the internal values via the reference and in latter you are changing the reference itself.
The difference here is that they are different.
In your first example you are passing the argument to another method, which is modifying one of its elements, which is visible at the caller. In the second case you are assigning the variable to a new value, which isn't visible at the caller, because Java has pass-by-value semantics.
NB 'Primary variable' has no meaning in Java.
I don't know what the word 'advance' in your title has to do with anything.
This question already has answers here:
Changing array in method changes array outside [duplicate]
(2 answers)
Closed 3 years ago.
public class Test {
public static void main(String[] args) {
int[] arr = new int[5];
arr[0] = 1;
method(arr);
System.out.println(arr[0]);
}
private static void method(int[] array)
{
array[0] = 2;
}
}
After invoking method, arr[0] becomes 2. Why is that!?
You can call set methods on objects passed to a method. Java is pass by value, which means that you can't replace an object in a method, though you can call set methods on an object.
If Java were pass by reference, this would pass:
public class Test {
public static void main(String[] args) {
Test test = new Test();
int j = 0;
test.setToOne(j);
assert j == 1;
}
public void setToOne(int i) {
i = 1;
}
}
Java is Pass-by-Value, Dammit! http://javadude.com/articles/passbyvalue.htm
This is because Java uses Call by Object-Sharing* (for non-primitive types) when passing arguments to method.
When you pass an object -- including arrays -- you pass the object itself. A copy is not created.
If you mutate the object in one place, such as in the called method, you mutate the object everywhere! (Because an object is itself :-)
Here is the code above, annotated:
public static void main(String[] args)
{
int[] arr = new int[5]; // create an array object. let's call it JIM.
// arr evaluates to the object JIM, so sets JIM[0] = 1
arr[0] = 1;
System.out.println(arr[0]); // 1
method(arr); // fixed typo :-)
// arr still evalutes to JIM
// so this will print 2, as we "mutated" JIM in method called above
System.out.println(arr[0]); // 2
}
private static void method(int[] array)
{
// array evaluates to the object JIM, so sets JIM[0] = 2
// it is the same JIM object
array[0] = 2;
}
Happy coding.
*Primitive values always have call-by-value semantics -- that is, a copy is effectively created. Since all primitive values are immutable this does not create a conflict.
Also, as Brian Roach points out, the JVM only implements call-by-value internally: the call-by-object-sharing semantics discussed above are implemented by passing the value of the reference for a given object. As noted in the linked wikipedia article, the specific terms used to describe this behavior differ by programming community.
Additional:
Pass by value or Pass by reference in Java? -- see aioobes answer and how it relates with Brian Roachs comments. And aioobe again: Does array changes in method?
Make copy of array Java -- note this only creates a "shallow" copy.
Because that's exactly what you're telling it to do. Java passes first by value, then by reference. You're passing in the array, but any modifications you make to that array will be reflected on any other accesses to that array.
A quick example for thought:
If within method you did array = null, no change would be visible from main - as you would be changing the local value of array without modifying anything on the reference.
Because when you are passing argument like int/double/char etc. they are the primitive data types and they are call by value - meaning their values are copied to a local variable in this method (that has the same name as the names in your argument) and changes made to them are only changes made to these local var -> does not affect your primitive type variables outside the method
however an array or any object data type is called by reference -> the argument pass their address(reference) to method. that way, you still have a local variable named by them which has the reference. You can change it to reference another array or anything. but when it is referencing an array, you can use it to set the value of the array. what it does is accessing the address it is referencing and change the content of the referenced place
method(arr[0]);
I think that's supposed to be
method(arr);
But anyway the value passed as argument to the method is the reference to the array and the local variable arr in the method is referencing the same array. So, within the method you are making changes to the same array.
Java is pass by value. What confuses people is that the 'value' of a variable that refers to an object allocated on the heap is a reference, so when you pass that, you pass the reference 'by value' and therefore it refers to the same object on the heap. Which means it doesn't matter from where you modify the referent; you're modifying the same thing.