Java Reference
In-Depth Information
Note that the static type of
rcvr
was declared to be
Object
. No static type informa‐
tion was used during the reflective invocation. The
invoke()
method also returns
Object
, so the actual return type of
hashCode()
has been autoboxed to
Integer
.
This autoboxing is one of the aspects of Reflection where some of the slight awk‐
wardness of the API can be seen—which is the subject of the next section.
g
R
e
l
e
c
t
i
o
n
Problems with Relection
Java's Reflection API is often the only way to deal with dynamically loaded code, but
there are a number of annoyances in the API that can make it slightly awkward to
deal with:
d
• Heavy use of
Object[]
to represent call arguments and other instances.
• Also
Class[]
when talking about types.
• Methods can be overloaded on name, so we need an array of types to distin‐
guish between methods.
• Representing primitive types can be problematic—we have to manually box
and unbox.
void
is a particular problem—there is a
void.class
, but it's not used consistently.
Java doesn't really know whether
void
is a type or not, and some methods in the
Reflection API use
null
instead.
This is cumbersome, and can be error prone—in particular, the slight verbosity of
Java's array syntax can lead to errors.
One further problem is the treatment of non-
public
methods. Instead of using
get
Method()
, we must use
getDeclaredMethod()
to get a reference to a non-
public
method, and then override the Java access control subsystem with
setAccessible()
to allow it to be executed:
public
class
MyCache
{
private
void
flush
()
{
// Flush the cache...
}
}
Class
<?>
clz
=
MyCache
.
class
;
try
{
Object
rcvr
=
clz
.
newInstance
();
Class
<?>[]
argTypes
=
new
Class
[]
{
};
Object
[]
args
=
null
;
Method
meth
=
clz
.
getDeclaredMethod
(
"flush"
,
argTypes
);
meth
.
setAccessible
(
true
);
meth
.
invoke
(
rcvr
,
args
);
}
catch
(
IllegalArgumentException
|
NoSuchMethodException
|
InstantiationException
|
SecurityException
e
)
{