As it might be clear from the title which approach should we prefer?
Intention is to pass a few method parameters and get something as output. We can pass another parameter and method will update it and method need not to return anything now, method will just update output variable and it will be reflected to the caller.
I am just trying to frame the question through this example.
List<String> result = new ArrayList<String>(); for (int i = 0; i < SOME_NUMBER_N; i++) { fun(SOME_COLLECTION.get(i), result); } // in some other class public void fun(String s, List<String> result) { // populates result }
versus
List<String> result = new ArrayList<String>(); for (int i = 0; i < SOME_NUMBER_N; i++) { List<String> subResult = fun(SOME_COLLECTION.get(i)); // merges subResult into result mergeLists(result, subResult); } // in some other class public List<String> fun(String s) { List<String> res = new ArrayList<String>(); // some processing to populate res return res; }
I understand that one passes the reference and another doesn’t.
Which one should we prefer (in different situations) and why?
Update: Consider it only for mutable objects.
Advertisement
Answer
Returning a value from the function is generally a cleaner way of writing code. Passing a value and modifying it is more C/C++ style due to the nature of creating and destroying pointers.
Developers generally don’t expect that their values will be modified by passing it through a function, unless the function explicitly states it modifies the value (and we often skim documentation anyway).
There are exceptions though.
Consider the example of Collections.sort
, which does actually do an in place sort of a list. Imagine a list of 1 million items and you are sorting that. Maybe you don’t want to create a second list that has another 1 million entries (even though these entries are pointing back to the original).
It is also good practice to favor having immutable objects. Immutable objects cause far fewer problems in most aspects of development (such as threading). So by returning a new object, you are not forcing the parameter to be mutable.
The important part is to be clear about your intentions in the methods. My recommendation is to avoid modifying the parameter when possible since it not the most typical behavior in Java.