I know there have been questions about the differences between lambdas and anonymous implementing an interface, but I wanted to examine the issue specifically for no-ops, that is, for an interface that I want to do nothing.
Let's say I create a static no-op implementation of AutoCloseable
:
private static final AutoCloseable NO_OP_AUTO_CLOSEABLE = () -> {};
I had assumed that this would just create an anonymous implementation of AutoCloseable
as if I would have done so manually, but (serendipitously through a separate bug in the code) I now see that it has created a special lambda implementation.
Do I gain anything by declaring a shared lambda for reuse, or is it just as efficient to use the lambda inline? And if I'm going to declare a static lambda, should I go ahead and use an anonymous implementation of the interface?
Here is the method I'm implementing:
public static AutoCloseable toAutoCloseable(Object object) {
return if(object instanceof AutoCloseable)
? (AutoCloseable)object
: NO_OP_AUTO_CLOSEABLE;
}
Obviously I wouldn't want to use new AutoCloseable(){…}
each time within the method. So in pre-lambda days, I would of course create a shared static version:
private static final AutoCloseable NO_OP_AUTO_CLOSEABLE = new AutoCloseable() {…};
But if it's creating a lambda anyway, would using a lambda inline be just as efficient?
public static AutoCloseable toAutoCloseable(Object object) {
return if(object instanceof AutoCloseable)
? (AutoCloseable)object
: ()->{};
}
Of course simply returning a reference must always be more efficient than creating anything, but are lambdas reused? What exactly happens when I say return ()->{}
? Is something new created each time, or is a reference created and then cached?
In short, how much less efficient is return ()->{}
over sending back a reference to an existing static instance, from an actual lambda implementation standpoint?
But as others have noted in closing this question, the answer to Is method reference caching a good idea in Java 8? explains this: it seems that a stateless lambda will result in some sort of handle to a reused lambda—there is no real benefit in trying to "cache" it manually by creating a static reusable instance.