Is there a method reference for a no-op (NOP) that

2019-02-05 10:45发布

问题:

This may sounds like a strange question, but is there a way to refer to a standard no-op (aka null operation, null-pattern method, no-operation, do-nothing method) method for a Lambda in Java 8.

Currently, I have a method that takes a, say, void foo(Consumer<Object>), and I want to give it a no-op, I have to declare:

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

where I would like to be able to do something like:

foo(Object::null)

instead. Does something like exist?

Not sure how that would work with multi-parameter methods -- perhaps this is a deficiency in the lambdas in Java.

回答1:

This is no deficiency.

Lambdas in Java are instances of functional interfaces; which, in turn, are abstracted to instances of Java constructs which can be simplified to one single abstract method, or SAM.

But this SAM still needs to have a valid prototype. In your case, you want to have a no-op Consumer<T> which does nothing whatever the T.

It still needs to be a Consumer<T> however; which means the minimal declaration you can come up with is:

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

and use NOOP where you need to.



回答2:

In your particular case you could simply do:

foo(i -> {});

This means that the lambda expression receives a parameter but has no return value.



回答3:

Could Function.identity() fit your needs?

Returns a function that always returns its input argument.



回答4:

If you want a method reference for a method that does nothing, the easiest way is to write a method that does nothing. Notice that in this example I have used Main::doNothing when a Consumer<String> is required.

class Main {

    static void doNothing(Object o) { }

    static void foo(Consumer<String> c) { }

    public static void main(String[] args) {
        foo(Main::doNothing);
    }
}

You could also overload doNothing by providing a version using varargs.

static void doNothing(Object... o) { }

This signature will accept literally any sequence of parameters (even primitives, as these will get autoboxed). That way you could pass Main::doNothing whenever the functional interface's method has void return type. For example you could pass Main::doNothing when an ObjLongConsumer<Integer> is needed.



回答5:

You can have your own NOOP implementation, similar to Function.Identity.

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