Passing a parameter versus returning it from function

13,320

Solution 1

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.

Solution 2

You should return it. The second example you provided is the way to go.

First of all, its more clear. When other people read your code, there's no gotcha that they might not notice that the parameter is being modified as output. You can try to name the variables, but when it comes to code readability, its preferable.

The BIG reason why you should return it rather than pass it, is with immutable objects. Your example, the List, is mutable, so it works okay. But if you were to try to use a String that way, it would not work.

As strings are immutable, if you pass a string in as a parameter, and then the function were to say:

public void fun(String result){
    result = "new string";
}

The value of result that you passed in would not be altered. Instead, the local scope variable 'result' now points to a new string inside of fun, but the result in your calling method still points to the original string.

If you called:

String test = "test";
fun(test);
System.out.println(test);

It will print: "test", not "new string"!

So definitely, it is superior to return. :)

Solution 3

This is more about best practices and your own method to program. I would say if you know this is going to be a one value return type function like:

function IsThisNumberAPrimeNumber{ }

Then you know that this is only going to ever return a boolean. I usually use functions as helper programs and not as large sub procedures. I also apply naming conventions that help dictate what I expect the sub\function will return. Examples:

GetUserDetailsRecords GetUsersEmailAddress IsEmailRegistered

If you look at those 3 names, you can tell the first is going to give you some list or class of multiple user detail records, the second will give you a string value of a email and the third will likely give you a boolean value. If you change the name, you change the meaning, so I would say consider this in addition.

Solution 4

The reason I don't think we understand is that those are two totally different types of actions. Passing a variable to a function is a means of giving a function data. Returning it from the function is a way of passing data out of a function.

If you mean the difference between these two actions:

public void doStuff(int change) {
    change = change * 2;
}

and

public void doStuff() {
    int change = changeStorage.acquireChange();
    change = change * 2;
}

Then the second is generally cleaner, however there are several reasons (security, function visibilty, etc) that can prevent you from passing data this way.

It's also preferable because it makes reusing code easier, as well as making it more modular.

Solution 5

according to guys recommendation and java code convention and also syntax limitation this is a bad idea and makes code harder to understand BUT you can do it by implementing a reference holder class

public class ReferenceHolder<T>{
        public T value;
}

and pass an object of ReferenceHolder into method parameter to be filled or modified by method. on the other side that method must assign its return into Reference value instead of returning it. here is the code for getting result of an average method by a ReferenceHolder instead of function return.

public class ReferenceHolderTest {
    public static void main(String[] args) {
        ReferenceHolder<Double> out = new ReferenceHolder<>();
        average(new int[]{1,2,3,4,5,6,7,8},out);
        System.out.println(out.value);
    }

    public static void average(int[] x, ReferenceHolder<Double> out ) {
        int sum=0;
        for (int a : x) {
            sum+=a;
        }
        out.value=sum/(double)x.length;
    }
}
Share:
13,320
instanceOfObject
Author by

instanceOfObject

Just a learner!!! #SOreadytohelp

Updated on July 21, 2022

Comments

  • instanceOfObject
    instanceOfObject almost 2 years

    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.

  • instanceOfObject
    instanceOfObject about 12 years
    Yup! That I understand, question was only for Mutable objects! Thanks for the reply btw!
  • SpacePrez
    SpacePrez about 12 years
    No problem. Yeah, for mutable objects it works, and in some cases it'll be preferable (you can't return multiple objects without using a tuple) but generally if its all the same, returning is better code style.