Callback functions in Java

Solution 1:

If you mean somthing like .NET anonymous delegate, I think Java's anonymous class can be used as well.

public class Main {

    public interface Visitor{
        int doJob(int a, int b);
    }


    public static void main(String[] args) {
        Visitor adder = new Visitor(){
            public int doJob(int a, int b) {
                return a + b;
            }
        };

        Visitor multiplier = new Visitor(){
            public int doJob(int a, int b) {
                return a*b;
            }
        };

        System.out.println(adder.doJob(10, 20));
        System.out.println(multiplier.doJob(10, 20));

    }
}

Solution 2:

Since Java 8, there are lambda and method references:

  • Oracle Docs: Lambda Expressions
  • Oracle Docs: Method References

For example, if you want a functional interface A -> B, you can use:

import java.util.function.Function;

public MyClass {
    public static String applyFunction(String name, Function<String,String> function){
        return function.apply(name);
    }
}

And here is how you can call it:

MyClass.applyFunction("42", str -> "the answer is: " + str);
// returns "the answer is: 42"

Also you can pass class method. For example:

@Value // lombok
public class PrefixAppender {
    private String prefix;

    public String addPrefix(String suffix){
        return prefix +":"+suffix;
    }
}

Then you can do:

PrefixAppender prefixAppender= new PrefixAppender("prefix");
MyClass.applyFunction("some text", prefixAppender::addPrefix);
// returns "prefix:some text"

Note:

Here I used the functional interface Function<A,B>, but there are many others in the package java.util.function. Most notable ones are

  • Supplier: void -> A
  • Consumer: A -> void
  • BiConsumer: (A,B) -> void
  • Function: A -> B
  • BiFunction: (A,B) -> C

and many others that specialize on some of the input/output type. Then, if it doesn't provide the one you need, you can create your own FunctionalInterface:

@FunctionalInterface
interface Function3<In1, In2, In3, Out> { // (In1,In2,In3) -> Out
    public Out apply(In1 in1, In2 in2, In3 in3);
}

Example of use:

String computeAnswer(Function3<String, Integer, Integer, String> f){
    return f.apply("6x9=", 6, 9);
}

computeAnswer((question, a, b) -> question + "42");
// "6*9=42"

And you can also do that with thrown exception:

@FunctionalInterface
interface FallibleFunction<In, Out, Ex extends Exception> {
    Out get(In input) throws Ex;
}
public <Ex extends IOException> String yo(FallibleFunction<Integer, String, Ex> f) throws Ex {
    return f.get(42);
}

Solution 3:

For simplicity, you can use a Runnable:

private void runCallback(Runnable callback)
{
    // Run callback
    callback.run();
}

Usage:

runCallback(new Runnable()
{
    @Override
    public void run()
    {
        // Running callback
    }
});