1

I have the following in class A:

static ArrayList<Student> students;

I have the following in class B:

public static void populate_students(ArrayList<Student> students) {
        students = new ArrayList<Student>();
// ...
}

in the debug mode, I see that student is initialized (not null) in the method but after returning to class A, student is null. Why is this the case? I thought that changes made on an object are visible from everywhere in Java.

Utku
  • 2,025
  • 22
  • 42
  • 1
    "*I thought that changes made on an object are visible from everywhere in Java.*" yes, to object, not to reference. – Pshemo May 25 '15 at 19:23
  • Actually java is always pass by value and not pass by reference. The value of an object is then it's reference. – sfrutig May 25 '15 at 19:26

3 Answers3

3

If you pass the static students variable to the populate_students, the method can change the state of the instance referred by that variable, but it can't assign a new value to that variable. So if you pass null to the method, the static variable will remain null after the method returns.

Instead, you need to return the List from the method :

public static ArrayList<Student> populate_students() {
    ArrayList<Student> students = new ArrayList<Student>();
// ...
    return students;
}

And assign it to the static variable :

static ArrayList<Student> students = B.populate_students();
Eran
  • 387,369
  • 54
  • 702
  • 768
3

Java is not pass-by-ref, it is pass-by-val (almost).

If you modify directly the students parameter without changing the reference, it modified value will be mutated to the original reference.

Exemple, Collections.sort(students..) will sort the list without having to catch it from a return.

However in your example, you re-assign a new list to students so your new students list in your method is not linked anymore to the old one.

I believe what you really want to do is

A.students = new ArrayList<Student>();
Jean-François Savard
  • 20,626
  • 7
  • 49
  • 76
2

There is no pass-by-reference in Java: primitives and references are passed by value. You cannot change a reference passed into your method by assigning it. If you saw students set to non-null value inside populate_students, it's because the debugger has figured out the new meaning of students from the context, and displayed the value of method's argument called students to you.

If you would like to produce a list in one method and set it into a variable inside a class, you can do it like this:

class A {
    static ArrayList<Student> students = B.populateStudents();
}
class B {
    public static ArrayList<Student> populateStudents() {
        ArrayList<Student> students = new ArrayList<Student>();
        ...
        return students;
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523