7
votes

In javascript, there's the common pattern of creating an anonymous function and immediately invoking it (usually this is called a self-executing anonymous function or an immediately-invoked function expression).

With Java 8 lambdas, is there a standard way to replicate this behaviour? Something like (() -> doSomething())().

This question asks basically the same question, but for Java 7. I'm explicitly looking for constructs which utilize lambdas.

2
@Holger No, lambdas are not implemented as inner classes.Brian Goetz
@Brian Goetz: I didn’t say inner classes. I just said anonymous classes…Holger
@Holger While technically correct, when you say "anonymous classes", 99.999% of the Java ecosystem hears "anonymous class" as defined by the language (i.e., "anonymous inner classes") -- very very few people know what VM-anonymous classes are -- and those who do, probably already know how lambdas are implemented. So, saying "they are implemented using anonymous classes" is guaranteed to confuse anyone who doesn't already know the actual story. Given that you were responding to OD, who almost certainly is thinking "anonymous inner class", makes it even more likely that you'll confuse.Brian Goetz
@Holger By all means feel free to take the discussion offline -- you should know how to reach me. My goal here is in not encouraging the myth that lambdas are "just" sugar for inner classes. They're semantically different (e.g., scoping rules), they're more efficient and optimizable, and they interact with other language features differently (e.g., type inference.) And yet the "lambdas are just inner classes" myth pervades. The name defineAnonymousClass was unfortunately ambigous; in this context, saying "anonymous class" at all invariably plays into this pervasive and unhelpful myth.Brian Goetz

2 Answers

13
votes

Not without declaring the type as well. Since Java is a statically-typed language, and functions are not first class citizens, the compiler needs to know what type your lambda is. A function can't just be free-floating, it always needs to be associated with either a class or an instance of a class.

Runnable r = () -> {
    System.out.println("Hello world!");
};
r.run();

But: You can cast the lambda to the Runnable type, and give the compiler a hint as to what kind of @FunctionalInterface you're implementing:

((Runnable)() -> {
    System.out.println("Hello world!");
}).run();

Or without the braces, which makes it a one-liner:

((Runnable)() -> System.out.println("Hello world!")).run();

I imagine that's about as close as you'll get!

2
votes

What about something like

((Runnable)(() -> System.out.println("Foobar"))).run();