I'm working on a Java question for my school which gives me this utility class:
import java.util.*;
public class PassByValue
{
private PassByValue() {}
public static void add(int a)
{
a = a + 1;
}
public static void add(Set<String> b)
{
b = new HashSet<String>();
b.add("ABC");
}
public static void add(List<Integer> c)
{
c.add(new Integer(1));
}
}
It also gives me this class with the main method
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class PassByValueClient
{
public static void main(String[] args)
{
PrintStream output = System.out;
int a = 1;
PassByValue.add(a);
output.println(a);
Set<String> b = new HashSet<String>();
PassByValue.add(b);
output.println(b.size());
List<Integer> c = new ArrayList<Integer>();
PassByValue.add(c);
output.println(c.size());
}
}
We are supposed to predict the output. When I predicted what the output would be, my guess was 1
, 0
, and 0
respectively. However, when I ran the code the output I got was 1
, 0
, and 1
respectively. From what I understand about passing parameters/arguments into methods, the client's code should remain unchanged. Can someone tell me why the output is 1
instead of 0
?
This is because the List, which gets handed over to PassByValue.add() points to a place in your storage (the address), the place (say the address 42) of your list. And when the list is in the method .add(), it still points to the same address (42)
If you change it, the data on that address (42) gets changed too. But both lists still point to the same address (42), so they point to the same data.
I'd like to explain whats happening in your example with pictures:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Variable "a"
Integer a = 1
This creates an address in your storage, to which the variable a
points to:
When you then pass it to the method PassByValue.add(a)
a new variable is created. But this new variable points to the same address (value).
When you then change it with a = a+1
, the variable doesn't point to the address anymore, but to a new one, with a new value.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Variable "b"
When you declare it an object is created pointing to a specific address:
When you hand it over there is another object created, which points to the same address:
When you set the object in PassByValue.add()
to = new HashSet<String>();
, it points to another address.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Variable "c"
Thats different when you change the object ITSELF.
Like you do it with the list.
By creating the List List<Integer> c = new ArrayList<>();
the variable points to a specific address.
When you hand it over to the .add()
-Method, a new variable is created, but it points to the same address.
And when you then change it by saying c.add(new Integer(1));
You change the object ITSELF. When you change the object ITSELF, the data stored on that address gets changed, but no new address-space gets created and both variables still point to the same address.