Java Reference
In-Depth Information
// defineClass() from ClassLoader
MethodType
mtdefClz
=
MethodType
.
methodType
(
Class
.
class
,
String
.
class
,
byte
[].
class
,
int
.
class
,
int
.
class
);
This single piece of the puzzle provides significant gains over Reflection, as it makes
method signatures significantly easier to represent and discuss. The next step is to
acquire a handle on a method. This is achieved by a lookup process.
g
R
e
l
e
c
t
i
o
n
d
Method Lookup
Method lookup queries are performed on the class where a method is defined, and
are dependent on the context that they are executed from. In this example, we can
see that when we attempt to lookup the protected
Class::defineClass()
method
from a general look up context, we fail to resolve it with an
IllegalAccessExcep
tion
, as the protected method is not accessible:
public
static
void
lookupDefineClass
(
Lookup
l
)
{
MethodType
mt
=
MethodType
.
methodType
(
Class
.
class
,
String
.
class
,
byte
[].
class
,
int
.
class
,
int
.
class
);
try
{
MethodHandle
mh
=
l
.
findVirtual
(
ClassLoader
.
class
,
"defineClass"
,
mt
);
System
.
out
.
println
(
mh
);
}
catch
(
NoSuchMethodException
|
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
}
Lookup
l
=
MethodHandles
.
lookup
();
lookupDefineClass
(
l
);
We always need to call
MethodHandles.lookup()
—this gives us a lookup context
object based on the currently executing method.
Lookup objects have several methods (which all start with
find
) declared on them
for method resolution. These include
findVirtual()
,
findConstructor()
, and
findStatic()
.
One big difference between the Reflection and Method Handles APIs is access con‐
trol. A
Lookup
object will only return methods that are accessible to the context
where the lookup was created—and there is no way to subvert this (no equivalent of
Reflection's
setAccessible()
hack).
Method handles therefore always comply with the security manager, even when the
equivalent reflective code does not. They are access-checked at the point where the
lookup context is constructed—the lookup object will not return handles to any
methods to which it does not have proper access.