Java Reference
In-Depth Information
The lookup object, or method handles derived from it, can be returned to other
contexts, including ones where access to the method would no longer be possible.
Under those circumstances, the handle is still executable—access control is checked
at lookup time, as we can see in this example:
public class SneakyLoader extends ClassLoader {
public SneakyLoader () {
super ( SneakyLoader . class . getClassLoader ());
}
public Lookup getLookup () {
return MethodHandles . lookup ();
}
}
SneakyLoader snLdr = new SneakyLoader ();
l = snLdr . getLookup ();
lookupDefineClass ( l );
With a Lookup object, we're able to produce method handles to any method we have
access to. We can also produce a way of accessing fields that may not have a method
that gives access. The findGetter() and findSetter() methods on Lookup pro‐
duce method handles that can read or update fields as needed.
Invoking Method Handles
A method handle represents the ability to call a method. They are strongly typed
and as typesafe as possible. Instances are all of some subclass of
java.lang.invoke.MethodHandle , which is a class that needs special treatment
from the JVM.
There are two ways to invoke a method handle— invoke() and invokeExact() .
Both of these take the receiver and call arguments as parameters. invokeExact()
tries to call the method handle directly as is, whereas invoke() will massage call
arguments if needed.
In general, invoke() performs an asType() conversion if necessary—this converts
arguments according to these rules:
• A primitive argument will be boxed if required.
• A boxed primitive will be unboxed if required.
• Primitives will be widened is necessary.
• A void return type will be massaged to 0 or null , depending on whether the
expected return was primitive or of reference type.
null values are passed through, regardless of static type.
With these potential conversions in place, invocation looks like this:
Search WWH ::




Custom Search