3

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.

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272
  • Using a named constant is always a good thing. – Seelenvirtuose Dec 31 '20 at 19:09
  • @Seelenvirtuose: I know that many people must agree with you, because I've seen many *useless* named constants -- things like `IS_SUCCESS = "IsSuccess"`, where the name doesn't tell you anything that the value doesn't, or like `setNumRetries(NUM_RETRIES)`, where the name doesn't tell you anything that the referencing context doesn't. (Of course, either of those *could* be useful as a place to hang useful Javadoc; but they never actually have Javadoc, so they don't even do that.) – ruakh Dec 31 '20 at 21:13

1 Answers1

2

No, this would provide no benefit. The design of lambdas is specifically so that Java can do this for you without any extra work.

Write your code to be as readable as possible.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413