Is Java pass-by-value or pass-by-reference?

The question if Java passes parameters by value or by reference seems to be one of the things newcomers to the Java language stumble upon quite often.

In general the answer is simple: Java is always pass-by-value.

What does this mean?

Pass-by-value means that you get a copy of the passed in object to work with, as opposed to a reference to it.

Let's exemplify.  Assume we have a method that manipulates a List object:

public void updateList(List list) {
    ..;
}

Now, assume we'd like to replace the passed-in list with another list we've created inside the method.  We might like to do something like:

public void updateList(List list) {
    List myList = new ArrayList();
    // add objects to myList
    list = myList; // replace list with my new list? *WRONG*
}

However, if we test this new method we'll find list has not changed at all.

This is because list is a copy of the object we passed-in to the method, and not the passed-in object itself.  list has been passed-by-value!

So, are we unable to change variables that are passed-in to a method in Java?  Can we only change them by returning a new object?

No.

And this is where the confusion sets in, because while we're unable to replace the passed-in object list with another object, we're perfectly allowed to manipulate it's member objects.

Basically this means if we want to replace a passed-in list with our own list we must do:

public void updateList(List list) {
    List myList = new ArrayList();
    // add objects to myList
    list.clear(); // empty passed-in list
    list.addAll(myList); // replace passed-in list with my new list!
}

Since we never try to replace list itself, the whole method works just fine and does what we expect.