All of the following print "Hello world!"
JavaScript:
console.log((function() {
const x = "Hello world!";
return x;
})());
Java:
System.out.println(((Supplier<String>) () -> {
String x = "Hello world!";
return x;
}).get());
In Java it may feel more ergonomic to create a helper function to infer the type and execute the function for you:
public static <T> T iife(Supplier<? extends T> supplier) {
return supplier.get();
}
...
System.out.println(iife(() -> {
String x = "Hello world!";
return x;
}));
In general you might want to consider factoring out the function. But if the function is relatively small, and especially if it captures several variables, an IIFE may be more readable. I liken an IIFE to a block expression (which Java does not have).