这可能听起来像是一个奇怪的问题,但是有没有办法在 Java 8 中引用 Lambda 的标准无操作(又名空操作、空模式方法、无操作、不执行任何操作的方法)方法。
目前,我有一个方法需要一个,比如说,
void foo(Consumer<Object>)
,我想给它一个无操作,我必须声明:
foo(new Consumer<Object>() {
public void accept(Object o) {
// do nothing
}
}
我希望能够做这样的事情:
foo(Object::null)
相反。有类似的东西存在吗?
不确定这如何与多参数方法一起工作——也许这是 Java 中 lambda 的缺陷。
这不是缺点。
Java 中的 Lambda 是函数式接口的实例;反过来,它们又被抽象为 Java 构造的实例,这些实例可以简化为一个单个抽象方法,或 SAM。
但是这个 SAM 仍然需要有一个有效的原型。就您而言,您希望有一个无操作
Consumer<T>
,它不执行任何操作 T
。
但是它仍然需要是
Consumer<T>
;这意味着您可以提出的最小声明是:
private static final Consumer<Object> NOOP = whatever -> {};
并在需要的地方使用
NOOP
。
在您的具体情况下,您可以简单地执行以下操作:
foo(i -> {});
这意味着 lambda 表达式接收参数但没有返回值。
BiConsumer<T, U>
的等效代码是:
void bifoo(BiConsumer<Object, Object> consumer) { ... }
bifoo((a, b) -> {});
您可以拥有自己的 NOOP 实现,类似于 Function.Identity。
static <T> Consumer<T> NOOP() {
return t -> {};
}
如果您想要一个不执行任何操作的方法的方法引用,最简单的方法是编写一个不执行任何操作的方法。请注意,在此示例中,当需要
Main::doNothing
时,我使用了 Consumer<String>
。
class Main {
static void doNothing(Object o) { }
static void foo(Consumer<String> c) { }
public static void main(String[] args) {
foo(Main::doNothing);
}
}
您还可以通过使用 varargs 提供版本来重载
doNothing
。
static void doNothing(Object... o) { }
此签名实际上将接受任何参数序列(甚至是原语,因为它们将被自动装箱)。这样,只要函数接口的方法具有
Main::doNothing
返回类型,您就可以传递 void
。例如,当需要 Main::doNothing
时,您可以传递 ObjLongConsumer<Integer>
。
如果您想要非常接近无操作的东西,您可以使用
Objects::requireNonNull
。
使用
x -> {}
当然也可以,但 IDE 的自动格式化程序可能会尝试将其分成多行。
我不喜欢 Java 设计团队忽略了
VoidSupplier
的概念。
我想要一个能够给我强类型的
@FunctionalInterface
的东西,这样我就不必将“忽略”的参数传递给不 return
任何东西的 lambda 函数(又名闭包)。
因此,我创建了一个类来填补这个明显的空白。
public class FunctionUtils {
private FunctionUtils() {
//Suppress instantiation
}
public static final VoidSupplier NO_OP = () -> {
};
@FunctionalInterface
public interface VoidSupplier {
void get();
}
}