Search code examples
javafunctionclassparametersvoid

Passing a null function to java function as argument


I'm encountering problems understanding how function are passed to methods as parameters.

Searching on StackOverflow and StackExchange has brought me to a solution using java.util.Functions

public void someFunction(Functions <int[], int[]> myFunction);

(source: https://codereview.stackexchange.com/questions/186972/passing-a-generic-function-as-parameter)

Although this solution seems good to me, I'm facing problem when I need to pass a function which is intended to do nothing. For better understanding, consider the following example:

public class Example {
    //do stuffs
    myFunction(null);
}

public class Manager {
    public void myFunction(Function<int[], void> funcToPass) { // Can't specify void as return value!
        //do stuff
        if(funcToPass != null) { // can't replicate such behaviour
            funcToPass(someParams)
        }
    }
}

Can someone help me acquiring clear understanding on this topic? Thank you so much.


Solution

  • If you want to describe a function that does not return a value, you can use the Void type. This is a standard Java class, but is intended for use in this situation.

    E.g.

    Function<String, Void> stringPrinter = s -> {
        System.out.println(s);
        return null;  // must return some value, null is acceptable since there is no Void instance
    };
    

    The return null; is important since, from the compiler's point of view, Void is just like any other class (e.g. String, Integer, etc). It doesn't know that it represents the absence of a value, whereas it does know that a function that returns void does not have a return value.

    This means the compiler still expects some return statement in your code, just as if it were returning an Integer, and so you must return null;

    EDIT:

    You may find, however, if you are strictly dealing with functions with no returns, you are better suited to use a Consumer<T>. For example:

    Consumer<String> stringPrinter = s -> System.out.println(s);
    stringPrinter.accept("hello");
    

    or, using a method reference:

    Consumer<String> stringPrinter = System.out::println;
    stringPrinter.accept("hello");