I thought I understood the concept of pass by value and reference in Java. But I just found out that I don't. 

Below are two methods that are being recursively called. In the first method, I am passing an array in the recursive calls, from top to bottom. When the condition is met, it prints the array and then returns. As the recursive calls return, the elements added to the array are removed with the return from each level. 

But if I use an `ArrayList`, the additions of elements to the list is permanent, even after all the recursive calls return. 

I assumed that in both cases, I am passing the array and `Arraylist` by reference (copy of reference) and I'm directly modifying the array. So whatever changes i make in the array, shouldn't it remain after the method returns? Please suggest, where am I getting it wrong.

I have not added the `print()`, I guess its evident from the output.

```
static void recurse(int[] list, int num) {
    if(num == 5) {  // print if condition is true
        print("Reached num = 5", list, num); 
        return;
    }
    list[num] = num;
    recurse(list,num+1);
    print("After recursive call returns ", list, num);// check elements in array
}

static void recurse(ArrayList<Integer> list, int num) {
    if(num == 5) {  // print if condition is true
        print("Reached num = 5", list); 
        return;
    }       
    list.add(num);
    recurse(list,num+1);
    print("After recursive call returns ", list); // check element of Arraylist
}
private static void print(String msg, ArrayList<Integer> list) {
    System.out.println(msg);
    System.out.println(list);       
}
private static void print(String msg, int[] list, int index) {
    System.out.println(msg);
    for(int i = 0 ; i < index; ++i)
        System.out.printf("%d ", list[i]);
    System.out.println();       
}

public static void main(String[] args) {
    ArrayList<Integer> arr1 = new ArrayList<>();
    recurse(arr1,0);
    int[] arr2 = new int[12];
    recurse(arr2,0);
}

```

Output from First

```
Reached num = 5
0 1 2 3 4 
After recursive call returns 
0 1 2 3 
After recursive call returns 
0 1 2 
After recursive call returns 
0 1 
After recursive call returns 
0 
After recursive call returns

```

Output from second

```
Reached num = 5
[0, 1, 2, 3, 4]
After recursive call returns 
[0, 1, 2, 3, 4]
After recursive call returns 
[0, 1, 2, 3, 4]
After recursive call returns 
[0, 1, 2, 3, 4]
After recursive call returns 
[0, 1, 2, 3, 4]
After recursive call returns 
[0, 1, 2, 3, 4]

```