Why is an ArrayList parameter modified, but not a String parameter?

Naresh picture Naresh · Apr 8, 2013 · Viewed 7.2k times · Source
public class StackOverFlow {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>();
        al.add("A");
        al.add("B");
        markAsNull(al);
        System.out.println("ArrayList elements are "+al);

        String str = "Hello";
        markStringAsNull(str);
        System.out.println("str "+ str);
    }
    private static void markAsNull(ArrayList<String> str){
        str.add("C");
        str= null;
    }
    private static void markStringAsNull(String str){
        str = str + "Append me";
        str = null;
    }
}

This outputs:

ArrayList elements are [A, B, C]
str Hello

In the case of ArrayList, the added elements are getting retrieved. In case of String the method call has no effect on the String being passed. What exactly is the JVM doing? Can anyone explain in detail?

Answer

Azodious picture Azodious · Apr 8, 2013

In the case of Arraylist string objects the added elements are getting retrived. In case of String the method call has no effect on the String being passed.

It happens cause Java is Pass-by-Value and Strings are immutable

When you call

markAsNull(ArrayList<String> str)

The a new reference by name str is created for the same ArrayList pointed by al. When you add an element on str it gets added to same object. Later you put str to null but the object has the new values added and is pointed by a1.

When you call

markStringAsNull(String str)
{
    str = str + "Append me";
    // ...
}

The line str = str + "Append me"; creates a new String object by appending the given string and assignes it to str. but again it is just reference to actual string which now pointing to newly created string. (due to immutablity) and the original string is not changed.