Hacker News new | ask | show | jobs
by badlogic 3980 days ago
Lambda inlining only works for very narrow scenarios. Passing a lambda to any Java API, such as event handlers in Android, will always have to resort to an anonymous class translation strategy, which generates a static or instance method in the outer class and a lambda class implementing the functional interface, forwarding to the outer class method. Non-capturing lambdas can be instantiated once and cached statically, forwarding to an outer class static method. Capturing lambdas can not be cached but still forward to an outer class static method. Lambdas capturing fields of the outer class can also not be cached and need to forward to an instance method of the outer class. Many lambdas passed to Android APIs will result in the last translation scheme.
1 comments

Thanks for the info! I did know that passing lambdas to Java API calls still has to instantiate an anonymous inner class, but the details about what happens in each situation are new to me (and really interesting).

I'm sorry that I didn't make it clearer in my post (I'll edit it), but the thing I really appreciate is that I can use functional methods on objects (like map, fold, filter on iterables or our monadic bind method on optionals) and pass lambdas because I know it will be inlined. The inlining -- which should always happen this particular scenario (please correct me if I'm wrong) -- makes using these methods super cheap!

Only a look at the resulting bytecode will tell you what happens in your scenarios :)
No need for bytecode when a stacktrace will do :-)

    public static void main(String... args) {
        Runnable r = () -> {
            ((Object)null).toString(); // kaboom
        };
        r.run();
    }