So at last night's SBJUG meeting the question arose as to the implementation of Java 8 Lambdas, and I answered incorrectly that they were implemented as anonymous inner classes. This was clearly wrong because javac
was not emitting any extra class files. Some perusing with javap
didn't shed light on the mystery - in fact, only making it deeper.
Watching Brian Goetz's excellent Java Lambdas: A Peek Under the Hood made it clear that something funny was going on. In fact, what is happening is that javac
is generating a synthetic method containing the body of the lambda (plus parameters that implement captured variables) and then using invokedynamic
and something called a "bootstrap method" to construct an object that uses that method to satisfy the constraints of the invocation. LambdaMetafactory has something to do with this machinery.
The reason we did not see the imul
operator was a mistake using javap
- in fact, all we needed was to add the -p option, which shows 'private' byte code. This in turn shows the generated method, lambda$main$0()
in the above javap output!
As an added bonus, I discovered that lambdas which do not capture variables are quite a lot faster than ones that do (~20x). So that should make a good demo.