java java8函数式接口来处理回调
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45499828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java8 functional interface to handle the callback
提问by zilcuanu
I have a generic private method which does common tasks and is used by other methods. The generic method has if
and else
conditions to support other methods that are called. Example:
我有一个通用的私有方法,它执行常见任务并被其他方法使用。通用方法if
和else
条件,支持被调用的其他方法。例子:
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 have created a functional interface called Invoker
with a invoke
method.
我想使用 Java 8 lambda,我创建了一个Invoker
用invoke
方法调用的函数式接口。
public interface Invoker{
public void invoke()
}
Now my generic method looks like this and the public method handles the invoke 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 creating this interface by myself?
JDK 中是否有一个功能接口可以使用,而不是自己创建这个接口?
回答by Szymon Stepniak
Package java.util.function
does not contain a functional interface with a method that does not require any parameter and returns void
. But you can use Runnable
interface instead.
包java.util.function
不包含具有不需要任何参数并返回 的方法的功能接口void
。但是您可以改用Runnable
接口。
private void myGenericMethod(Runnable runnable){
common task1;
common task2;
//consider checking if runnable != null to avoid NPE
runnable.run();
}
Then the invocation would look pretty simple:
然后调用看起来非常简单:
myGenericMethod(() -> {
//do something fancy
System.out.println("Hello, world!");
});
Other options
其他选项
There are other functional interfaces you may be interested in, for example:
您可能对其他功能接口感兴趣,例如:
Supplier<T>
if you want to return a value ofT
without passing any parametersFunction<T,R>
if you want to pass a value ofT
and return a value ofR
Consumer<T>
if you want to pass valueT
as a parameter and returnvoid
Supplier<T>
如果你想在T
不传递任何参数的情况下返回一个值Function<T,R>
如果你想传递一个值T
并返回一个值R
Consumer<T>
如果要将值T
作为参数传递并返回void
Why there is no alternative for Runnable
interface?
为什么Runnable
接口没有替代品?
Using Runnable
interface for a lambda that does not return nothing and does not expect any parameters may sound controversial for many programmers. Runnable
was invented for running a code in a separate thread and many programmers identify this class with multithreading. Even documentationsays:
Runnable
对不返回任何内容且不期望任何参数的 lambda使用接口对于许多程序员来说可能听起来有争议。Runnable
是为了在单独的线程中运行代码而发明的,许多程序员将这个类标识为多线程。甚至文档说:
The
Runnable
interface should be implemented by any class whose instances are intended to be executed by a thread.
该
Runnable
接口应该由其实例旨在由线程执行的任何类实现。
Someone already asked similar question2 years ago and if you take a look at this commentand Brian Goetz'sreaction to it you will understand that Java language designers came to a conclusion that there is no need to create another functional interface that mimics implementation of Runnable
interface.
两年前有人已经问过类似的问题,如果你看看这个评论和Brian Goetz 的反应,你就会明白 Java 语言设计者得出的结论是,没有必要创建另一个模拟Runnable
接口实现的函数式接口。
回答by Murat Karag?z
There is also the possibility to use Consumer<Void>
. It could look like this
也有可能使用Consumer<Void>
. 它看起来像这样
public void init(Consumer<Void> callback) {
callback.accept(null);
}
init((Void) -> done());
回答by Jo?o Pedro Schmitt
I suggest to use Consumer as callback interface. Comparing it with the JavaScript language, callbacks are bound with a scope. Therefore, if you make use of Consumer interface then you can pass the scope as parameter to the function. Ex:
我建议使用 Consumer 作为回调接口。与 JavaScript 语言相比,回调与作用域绑定。因此,如果您使用 Consumer 接口,那么您可以将范围作为参数传递给函数。前任:
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);
}