Always remember that Java is pass by value.
If you reinstantiate a variable inside a method, the passed variable is left untouched. Your example does exactly that.
String myValue = "All your variables belong to us";
setValue(myValue);
System.out.println(myValue); //All your variables belong to us
void setValue(String v){
v = "Hello World!";
}
You should initialize first your variable:
import java.util.ArrayList;
public class One {
private ArrayList<Integer> list = new ArrayList<Integer>();
public One() {
addString(list);
sysoutList(list);
}
public void sysoutList(ArrayList<Integer> list2) {
for (int i = 0; i < list2.size(); i++) {
System.out.println(list2.get(i));
}
}
private void addString(ArrayList<Integer> list2) {
list2.removeAll();
list2.add(1);
list2.add(2);
list2.add(3);
list2.add(4);
}
}
A list is a special case tough. You could think with the add() method I'm pratically modifying the variable, so the modification shouldn't occur. That's not true, why?
That's because you are passing the value of the reference for the list. If you assign a new value to that reference using the new
keyword, you "loose" the object attached to it (you don't have its reference anymore).
But if you modify a property of that object (such as with the add() method) the reference for the object is still valid and thus you modify the original object.
We can make a similitude.
Imagine you have a kite attached to a string. Now you attach a new string to it and pass the newly created string to a friend.
If he cuts the string (aka creates a new
one), he loses the reference to your kite and he can't reach it. He can attach a new kite and do all the modifications (aka add()
something to it) that he wants, but it will never be your kite.
If he instead uses the string you gave to him to reach the kite and modify it, you'll receive a modified kite.
To remain in the similitude in your case you are creating a string with no kite (list
) with private ArrayList<Integer> list;
and then passing it to your friend creating a new string (list2
). Now both you and your friend have a string with nothing attached.
He creates a new kite and attaches it to his string (list2 = new ArrayList<>()
) but your string is still attached to nothing. When you try to fly your kite you'll notice that the kite simply doesn't exists (null
reference).
First you have to create your own kite and attach your string (private ArrayList<Integer> list = new ArrayList<Integer>();
). When you pass it to your friend another string is attached to it (list2
). Now your friend can use list2
to modify your kite.
EDIT
Regarding your other question, if is possible to istantiate a variable in a method which is called from the constructor the answer is yes, but such variable MUST be declared as static
if you want to use it outside your method.
In the kite similitude is like you attach a kite to a string and you and your friend use the same string to operate on it (yep, holding hands).
For you becomes:
import java.util.ArrayList;
public class One {
private static ArrayList<Integer> list;
public One() {
addString();
sysoutList();
}
public void sysoutList() {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
private void addString() {
list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
}
}
You don't need to pass the ArrayList
around since you are using the same "kite string" everywhere in your program.
NB: If you call sysoutList()
before addString()
you'll still get a NullPointerException
because list isn't initialized yet.
This is a bad practice. I firmly suggest you to change your logic.