Java Reference
In-Depth Information
variable and then invoking the superclass constructor on it. The command aload_0 pushes onto the stack
the local variable at offset 0 in the local variable table: that is our this variable. At that point, we have a
stack whose top element is our this variable. Constructors are strange kinds of beasts, so you invoke them
in bytecode by saying invokespecial . You need to tell the runtime what constructor you are invoking, so
you call invokespecial with a method reference: in our code, the method reference is the Object class
constructor. With all of that accomplished, we return . (Remember, a constructor is a void method according
to bytecode.)
At this point, I do not expect that you feel like a bytecode expert. However, you should no longer be
overwhelmed or lost when looking at Listing 8-1. You should have a general sense as to how to read a basic
class. With that skill, we can move into reading the bytecode that backs lambdas.
Method References in Bytecode
In terms of bytecode, the simplest kind of lambda is the method reference. In Listing 8-2, we will
construct a method reference to the static method Listing2::lambdiseMe . That method is coerced into a
Supplier<String> . The result of this relatively short bit of Java is a lot of additional bytecode in the class,
and we might start to feel overwhelmed or lost again, but we will take it step by step to see what is going on.
Before we get into the bytecode, let's be clear about what we are doing in Java. We are going to declare a
static method, lambdiseMe , that takes no arguments and returns a String value. We will also declare another
static method, getSupplier , that takes no arguments and returns a Supplier<String> . All getSupplier
will do is return a reference to lambdiseMe . This is simple stuff that we have been doing since Chapter 2.
The result is in Listing 8-2. The javap result is a bit too long, so we omitted the constant pool, the default
constructor, and some of the other extraneous details.
Listing 8-2. Java Code for a Static Method Reference with Its Bytecode (Abbreviated)
1 // Listing2.java, which is compiled to Listing2.class
2 import java.util.function.*;
3
4 public class Listing2 {
5
6 public static String lambdiseMe() {
7 return "Hello, World!";
8 }
9
10 public static Supplier<String> getSupplier() {
11 return Listing2::lambdiseMe;
12 }
13
14 }
15
16 // Abbreviated result of executing /usr/bin/javap -v -l -p -s -c Listing2 in the same
directory as Listing2.class
17 public class Listing2
18 BootstrapMethods:
19 0: #24 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(
Ljava/lang/invoke/MethodHandles$Lookup;
Ljava/lang/String;
Ljava/lang/invoke/MethodType;
 
Search WWH ::




Custom Search