首页 文章

是否存在可用于任何lambda的无操作(NOP)的方法参考?

提问于
浏览
48

这可能听起来像一个奇怪的问题,但有没有办法在Java 8中引用Lambda的标准无操作(即null操作,空模式方法,无操作,无操作方法)方法 .

目前,我有一个方法,例如, void foo(Consumer<Object>) ,我想给它一个no-op,我必须声明:

foo(new Consumer<Object>() { 
  public void accept(Object o) { 
    // do nothing 
  }
}

我希望能够做的事情:

foo(Object::null)

代替 . 有类似存在吗?

不确定多参数方法如何工作 - 也许这是Java中lambdas的缺陷 .

5 回答

  • 40

    这不是缺陷 .

    Java中的Lambdas是功能接口的实例;反过来,它被抽象为Java构造的实例,可以简化为单个抽象方法或SAM .

    但是这个SAM仍然需要有一个有效的原型 . 在你的情况下,你想要一个no-op Consumer<T> ,无论 T 什么都不做 .

    它仍然需要是 Consumer<T> 然而;这意味着您可以提出的最小声明是:

    private static final Consumer<Object> NOOP = whatever -> {};
    

    并在需要的地方使用 NOOP .

  • 3

    在您的特定情况下,您可以简单地做:

    foo(i -> {});
    

    这意味着lambda表达式接收参数但没有返回值 .

  • 20

    Function.identity()能满足您的需求吗?

    返回一个始终返回其输入参数的函数 .

  • 7

    如果你想要一个什么都不做的方法的方法引用,最简单的方法是编写一个什么都不做的方法 . 请注意,在此示例中,当需要 Consumer<String> 时,我使用了 Main::doNothing .

    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) { }
    

    这个签名将接受任何参数序列(甚至原语,因为这些将被自动装箱) . 这样,只要函数接口的方法具有 void 返回类型,就可以传递 Main::doNothing . 例如,当需要 ObjLongConsumer<Integer> 时,您可以传递 Main::doNothing .

  • 9

    您可以拥有自己的NOOP实现,类似于Function.Identity .

    static <T> Consumer<T> NOOP() {
        return t -> {};
    }
    

相关问题