Java Reference
In-Depth Information
15 Method arguments:
16 #21 (Ljava/lang/Object;)Ljava/lang/Object;
17 #22 invokevirtual java/math/BigInteger.toString:()Ljava/lang/String;
18 #23 (Ljava/math/BigInteger;)Ljava/lang/String;
19 {
20 public static java.util.function.Function<java.math.BigInteger, java.lang.String>
21 Code:
22 stack=1, locals=0, args_size=0
23 0: invokedynamic #2, 0
// InvokeDynamic #0:apply:()Ljava/util/function/Function;
24 5: areturn
25 }
It may seem like the free instance method is the strangest of all three types of method references, but
the actual implementation is just as simple as the static method reference! Just like in Listing 8-2, we see a
single invokedynamic call followed by a return. The bootstrap method is also the same. The only difference
is that the method handle passed into the bootstrap uses invokevirtual instead of invokestatic . This
goes to show that the invokevirtual and the invokestatic calls are not directly invoked, but are instead
implementation details about the functional interface itself. So there is no difference between creating a
static and a free instance method, except in the way the implementation calls the methods.
Inline Lambda Definitions and Lambda Lifting
The last kind of lambda that you can have is a lambda with an inline definition. We are not talking about a
reference to an existing method here, but instead defining an entirely new unit of functionality right inline.
You may consider code like this:
public Supplier<String> getSupplier() {
return () -> "Hello, World!";
What the compiler will do in this case is create a method for you with that implementation. That is
called a “synthetic method.” This will be a static method that takes no arguments and returns the string,
“Hello, World!” Once that is created, the compiler has now reduced the problem of the inline lambda into
the static method reference problem that we saw before. It is a quite clever solution, and ultimately quite
trivial an implementation - which means it is boring for us.
The more interesting case is when you have variables in the mix. Let's create a method that calls an
instance method (requiring access to this ) along with a local variable in the scope. After all, these lambdas
are closures: they enclose their scope. This kind of stuff is their job! How is the compiler going to deal with
that complexity? The answer is in Listing 8-5.
Search WWH ::

Custom Search