Java8 functional interface to handle callback
I have a general private method that does common tasks and is used by other methods. The general method has the conditions if
and else
to support other methods caused. Example:
private void myGenericMethod(String name, int age){
common task1;
common task2;
if(name!= null && name.length > 0){
specific task 1;
specific task 2;
} else{
specific task 3;
specific task 4;
}
if(age > 18){
specific task 1`;
specific task 2`;
}
}
I want to use Java 8 lambda and I created a functional interface called Invoker
using method invoke
.
public interface Invoker{
public void invoke()
}
Now my generic method looks like this, and the public method handles the callback function callback appropriately:
private void myGenericMethod(Invoker invoker){
common task1;
common task2;
invoker.invoke();
}
Is there a functional interface in the JDK that I can use instead of building this interface myself?
source to share
The package java.util.function
does not contain a functional interface with a method that does not require any parameters and returns void
. But you can use . Runnable
private void myGenericMethod(Runnable runnable){
common task1;
common task2;
//consider checking if runnable != null to avoid NPE
runnable.run();
}
Then the call will look pretty simple:
myGenericMethod(() -> {
//do something fancy
System.out.println("Hello, world!");
});
Other options
There are other functional interfaces that may interest you, for example:
-
Supplier<T>
if you want to return a valueT
without passing any parameters -
Function<T,R>
if you want to pass valueT
and return valueR
-
Consumer<T>
if you want to pass the valueT
as a parameter and returnvoid
Why is there no alternative for the interface Runnable
?
Using an interface Runnable
for a lambda that doesn't return anything, and doesn't expect any parameters to seem controversial to many programmers. Runnable
was invented to run code on a separate thread, and many programmers identify this class with multithreading. Even the documentation says:
The interface
Runnable
must be implemented by any class whose instances are intended to be executed by a thread.
Someone already asked a similar question 2 years ago, and if you watch this comment and Brian Goetz's reaction to it, you will realize that the Java language designers have come to the conclusion that there is no need to create another functional interface that mimics the interface implementation Runnable
.
source to share
You need an interface Runnable
!
https://docs.oracle.com/javase/7/docs/api/java/lang/class-use/Runnable.html
It has a method run
that is similar to your method invoke
.
Feel free to use this though if you think yours is Invoker
more readable in your particular situation. Perhaps you are using something that says "invoke x" is more natural than "run x". Just remember to annotate yours Invoker
with @FunctionalInterface
so you can use lambdas with it.
source to share
I suggest using Consumer as your callback interface. Comparing it to JavaScript, callbacks are scoped. Therefore, if you are using the Consumer interface, you can pass the scope as a parameter to the function. Example:
public void startTracer(String tracerName, Event boundEvent) {
executeOnTracer(tracer -> tracer.startTracer(tracerName, boundEvent));
}
...
private void executeOnTracer(Consumer<Tracer> callback) {
TracerController tracer = null;
if (isTracerActive()) {
tracer = getTracer();
}
Optional.ofNullable(tracer).ifPresent(callback::accept);
}
source to share