for example:
public static void main(String[] args)throws InterruptedException {
List<String> l1 = new LinkedList<String>();
String[] s1 = {"aa","bb","cc","dd"};
for(String k : s1)
l1.add(k);
removeStuff(l1,1,2);
printList(l1);
}
private static void printList(List<String> l) {
for(String b : l){
System.out.print(b + ' ');
}
private static void removeStuff(List<String> l, int i, int j) {
l.subList(1, 3).clear();
}
it will print aa dd instead of aa bb cc dd. So I am just wondering that, since java is "pass-by-value", how could the linkedlist l1 be changed by the method removeStuff?
Java has a lot of history and the
pass by value
law wasn't the best idea. The problem is that an object reference is considered avalue
. So technically, yes, you are passing values around. However, these values reference points in memory, and those memory addresses can be modified by other methods.When you pass the list to a method, the value you are passing is actually a reference to the list in memory.
Java is pass by value, but when you pass an object into a method, it is passing a copy of the reference to that object.
Think of every reference as a "pointer" to an object. The outer method has a reference to the list and the method you call gets a reference to it, too. They both have their own "pointer" that points to the same place.
If one of the methods modifies the object, they are modifying what the reference points to. Since both of their references are pointing to the same place, that means they both see the effect.
Java is pass by value, but the value passed is the reference to the object in memory. Specifically
l1
points to a list, when you call a method, the variablel1
isn't passed (that would be pass by reference), but the value ofl1
is passed, this value is a reference to the same object. If you reassign the argumentl
with a differentList
, then the variable in the caller (l1
) is unchanged.Specifically in your example this is further compounded by the fact that
List.subList
is a view on the underlying list. Modifying the sublist (in your code callingclear()
) will also modify the backing original list.Your specific example is even included in the API documentation:
Java uses pass by reference for an object, but the reference is the alias to the same memory location not the original variable. That is why some people who do not get it say that Java uses always pass by value, which is half true. So the alias is pointing to the same memory as original variable but it is not the original variable. As long as you don't change the alias memory address you can manipulate the elements of the LIST the same way as using the original variable. I hope it is clear enough to understand.