Java Reference
In-Depth Information
It is possible that this variable came from some other classloader far away, or that it was somehow
gamed into existence. The bootstrap method, however, is going to need access to the class, and is going to
need it to be fully formed. To ensure that the class is fully loaded and accessible in the current context, we
will call the Object.getClass() method on System.out . The invokevirtual call, however, will consume
the top element of the stack as the target, and we want to keep the top element around - it's our reference
to System.out . So we first do a dup , which duplicates the top element of the stack. The stack now has two
System.out references, and we consume one with invokevirtual to call the Object.getClass() method.
We don't want to actually do anything with the class, however, so we can then just pop it off the stack.
This class maneuver is the kind of bookkeeping that you do not have to deal with in the world of Java,
and which the compiler provides to you free of charge. It also demonstrates the subtlety and complexity of
bootstrapping and method handle lookups, which it is very easy to get wrong. So please love and appreciate
your compiler!
Free Instance Method References in Bytecode
There is one last kind of method reference: the free instance method reference. This is the case when we
pass in a type and an instance method to the method reference, and it creates a method that accepts that
type and calls the given instance method. This is somewhat like the bound method reference, in that it has to
track what type is being called. However, we do not have a particular instance that is being called in this case,
so it can't act like the bound instance method reference. How does it work?
To demonstrate this, we will create a method that will return the BigInteger::toString free instance
method reference. This free instance method reference requests a BigInteger to call, and returns a String .
The shape of this, therefore, is Function<BigInteger,String> . The resulting method and its abbreviated
bytecode is in Listing 8-4.
Listing 8-4. Java Code for a Free Instance Method Reference with Its Bytecode (Abbreviated)
1 // Listing4.java, which is compiled to Listing4.class
2 import java.math.BigInteger;
3 import java.util.function.*;
4
5 public class Listing4 {
6 public static Function<BigInteger, String> getFunction() {
7 return BigInteger::toString;
8 }
9 }
10
11 // Abbreviated result of executing /usr/bin/javap -v -l -p -s -c Listing4 in the same
directory as Listing4.class
12 public class Listing4
13 BootstrapMethods:
14 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;
 
Search WWH ::




Custom Search