Java 8将方法作为参数传递

74

我目前正在学习Java 8中的lambda表达式和方法引用。

我想将一个没有参数和返回值的方法作为参数传递给另一个方法。这是我的做法:

public void one() {
    System.out.println("one()");
}

public void pass() {
    run(this::one);
}

public void run(final Function function) {
    function.call();
}

@FunctionalInterface
interface Function {
    void call();
}

我知道在java.util.function中有一组预定义的函数接口,例如Function<T,R>,但我没有找到一个不带参数且不产生结果的接口。


6
没关系,Runnable 也可以。Supplier<Void>, Function<Void, Void> - Joop Eggen
哦,是的,好老的Runnable...我知道我错过了一些显而易见的东西!你应该把这个作为答案,因为你回答了我的问题 :-) - Torsten Römer
2个回答

66

其实并不重要;Runnable 也可以。

Consumer<Void>,
Supplier<Void>,
Function<Void, Void>

14
Runnable 是最好的选择。如果你使用 Supplier<Void> 或者 Function<Void,Void>,由于返回类型是 Void 而不是 void,你可能被迫提供 null 作为返回值;而对于 Consumer<Void>,你可能需要声明一个虚拟参数。 - Stuart Marks
1
@StuartMarks,这个评论肯定会帮助其他人通过他们的风格感进行选择。奇怪的是没有java.util.Action/SideEffect或类似的东西。 - Joop Eggen
6
这些接口的问题在于它们没有语义,完全是结构性的。语义来自于它们的使用方式。由于它们可以以许多不同的方式使用,给它们命名非常困难。一个接口,它接收一个事件并返回空值,被称为 Action 而不是 Consumer<Event> 是有道理的,但在其他情况下,Action 则不太合适。因此,这些名称大多选择反映了结构,也就是传递的参数和返回的值。 - Stuart Marks
@StuartMarks 同意,由于Lambda函数通常是匿名使用的,甚至可以使用“_”(下划线)作为函数名称。总的来说,“Function”是一个很好的中性捕获所有情况的名称,虽然“Void”缺少void作为返回值,而“()”则表示参数值。 - Joop Eggen

46

你也可以这样传递 lambda:

public void pass() {
    run(()-> System.out.println("Hello world"));
}

public void run(Runnable function) {
    function.run();
}

这样做,你直接将lambda作为方法传递。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接