简体   繁体   中英

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.

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.

Eg

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 (eg 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");

You can use Reflection API to pass a void method as a reference eg

import java.lang.reflect.Method;

public class Main {

    public static void main(String[] args) throws Exception {
        Class[] classParams = new Class[1];
        classParams[0] = String.class;
        Method method = Main.class.getMethod("hello", classParams);
        Main obj = new Main();
        System.out.println(new Main().getSum(obj, method, "world!", 10, 20));
    }

    public void hello(String msg) {
        System.out.println("Hello " + msg);
    }

    int getSum(Object object, Method method, String msg, int x, int y) throws Exception {
        Object[] objectParams = new Object[1];
        objectParams[0] = msg;
        method.invoke(object, objectParams);
        return x + y;
    }
}

Output:

Hello world!
30

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM