Java Reference
In-Depth Information
Listing 8-3.
Java Code for a Bound Instance Method Reference with Its Bytecode (Abbreviated)
1 // Listing3.java, which is compiled to Listing3.class
2 import java.util.function.*;
3 public class Listing3 {
4 public Consumer<String> getConsumer() {
5 return System.out::println;
6 }
7 }
8
9 // Abbreviated result of executing /usr/bin/javap -v -l -p -s -c Listing3 in the same
directory as Listing3.class
10 public class Listing3
11 BootstrapMethods:
12 0: #25 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(
Ljava/lang/invoke/MethodHandles$Lookup;
Ljava/lang/String;
Ljava/lang/invoke/MethodType;
Ljava/lang/invoke/MethodType;
Ljava/lang/invoke/MethodHandle;
Ljava/lang/invoke/MethodType;
)Ljava/lang/invoke/CallSite;
13 Method arguments:
14 #26 (Ljava/lang/Object;)V
15 #27 invokevirtual java/io/PrintStream.println:(Ljava/lang/String;)V
16 #28 (Ljava/lang/String;)V
17 {
18 public java.util.function.Consumer<java.lang.String> getConsumer();
19 LocalVariableTable:
20 Start Length Slot Name Signature
21 0 14 0 this LListing3;
22 Code:
23 stack=2, locals=1, args_size=1
24 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
25 3: dup
26 4: invokevirtual #3
// Method java/lang/Object.getClass:()Ljava/lang/Class;
27 7: pop
28 8: invokedynamic #4, 0 // InvokeDynamic
// #0:accept:(Ljava/io/PrintStream;)Ljava/util/
function/Consumer;
29 13: areturn
30 }
If we compare this to the function in 8-2, we see that there is a bit more going on. The first thing is
the
getstatic
call, which loads
System.out
onto the stack. Eventually, we will pass that instance into
our
invokedynamic
call on instruction 8, which will again go by way of the bootstrap method to produce
our Consumer. The bootstrap method is practically identical to what we saw with the static method
reference, except that our method is being invoked using
invokevirtual
instead of
invokestatic
. Whereas
invokestatic
makes the static method call,
invokevirtual
makes an instance method call. So that is our
method reference, and the instance to invoke it on is also passed into the bootstrap method. Aside from that
difference, this is all very similar to what we saw before. But what is that stuff in instructions 3, 4, and 7?