我有一个通用的私有方法,它执行常见任务并被其他方法使用。泛型方法具有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`;
}
}
我想使用Java 8 lambda,并使用Invoker
方法创建了一个名为invoke
的功能接口。
public interface Invoker{
public void invoke()
}
现在我的泛型方法看起来像这样,公共方法适当地处理调用函数回调:
private void myGenericMethod(Invoker invoker){
common task1;
common task2;
invoker.invoke();
}
我可以使用JDK中的功能接口而不是自己创建这个接口吗?
答案 0 :(得分:19)
包java.util.function
不包含带有不需要任何参数的方法的函数接口,并返回void
。但您可以使用Runnable
界面。
private void myGenericMethod(Runnable runnable){
common task1;
common task2;
//consider checking if runnable != null to avoid NPE
runnable.run();
}
然后调用看起来很简单:
myGenericMethod(() -> {
//do something fancy
System.out.println("Hello, world!");
});
您可能感兴趣的其他功能接口,例如:
Supplier<T>
如果您想在不传递任何参数的情况下返回值T
Function<T,R>
如果您想传递T
的值并返回值R
Consumer<T>
如果您想将值T
作为参数传递并返回void
Runnable
接口没有其他选择?对于没有返回任何内容并且不期望任何参数的lambda使用Runnable
接口可能对许多程序员来说都是有争议的。 Runnable
是为在单独的线程中运行代码而发明的,许多程序员使用多线程来识别这个类。即使documentation说:
Runnable
接口应由任何其实例打算由线程执行的类实现。
2年前有人already asked similar question如果你看看this comment和Brian Goetz's对它的反应,你就会明白Java语言设计师得出的结论是没有必要创建另一个模仿Runnable
接口实现的功能接口。
答案 1 :(得分:1)
也可以使用Consumer<Void>
。看起来像这样
public void init(Consumer<Void> callback) {
callback.accept(null);
}
init((Void) -> done());
答案 2 :(得分:0)
我建议使用Consumer作为回调接口。与JavaScript语言相比,回调是通过范围绑定的。因此,如果您使用使用者接口,则可以将范围作为参数传递给函数。 例如:
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);
}