-1
public List<String> generateParenthesis(int n) {
        List<String> list = new ArrayList<String>();
        backtrack(list, "", 0, 0, n);
        return list;
    }
    
    public void backtrack(List<String> list, String str, int open, int close, int max){
        
        if(str.length() == max*2){
            list.add(str);
            return;
        }
        
        if(open < max)
            backtrack(list, str+"(", open+1, close, max);
        if(close < open)
            backtrack(list, str+")", open, close+1, max);
    }

In the above code 'list' is a List of strings defined in generateParenthesis(). In backtrack(list, "", 0, 0, n); they don't store the value of list returned by backtrack() but when the final list is returned in return list; the value of list is as returned by backtrack()

My question is: why is the instance of 'list' variable created in generateParenthesis() getting modified even though it is not a static variable and neither is the value returned by backtrack() function is being stored in 'list' by using an assignment operation like list=backtrack(list, "", 0, 0, n); ?

  • IMHO the confusion already starts when you talk about `list` being a List of strings. It is **not** a List of strings - it is **a reference** to a List of strings. And anyone having a copy of that reference (to a List of strings) can manipulate that referenced List of strings. – Thomas Kläger Feb 28 '23 at 07:56

1 Answers1

0

Java uses, as you said, pass by value when talking about function calls.

If you had something like that:

static void process(int a) {
    a = a + 3;
}

public static void main(String[] args) {
    int a = 5;
    process(a);
    System.out.println(a); // still 5
}

a = 5 would be your final value.

Now, in the case of objects (also the Lists, which are still objects), you are still passing by value, but the value stored in the List object sent as a parameter is a reference to the instance of the object in memory.

On the heap, you have a List instance, and on the stack, you have a List object. Whenever you call a method on a List object, it is called on the single instance from the heap. So List will get modified.

A good example which shows that a pass by value happens in your case is trying to modify the instance your object refers to:

public void backtrack(List<String> list, String str, int open, int close, int max){
    list = new ArrayList<String>(); // this should reset the list, but only resets it within the function. It won't get modified outside the function
Mario Mateaș
  • 638
  • 7
  • 25