Java Reference
In-Depth Information
A parameterized
Class
type is known as the
type token
for a given class.
The easiest way to obtain a type token is to use a class literal, such as
String.class
, since this provides you with the exact type token. In con-
trast,
Class.forName
is declared to return a wildcard,
Class<?>
, that rep-
resents an unidentified type tokento use this type token effectively you
need to establish its actual type, as you'll soon see. The
Object
method
getClass
returns the type token for the type of object it is invoked on,
and its return type is also
Class<?>
, another wildcard. However,
getClass
receives special treatment by the compiler: If
getClass
is invoked on a
reference with static type
T
, then the compiler treats the return type of
[1]
It actually treats it as being
Class<? extends S>
, where
S
is the erasure of
T
. Parameterized types
share the same
Class
object so the erasure is used to remove any parameterized types from the wild-
card's bounds. For example, given
List<String> l
, then
l.getClass()
has the type
Class<? extends
List>
.
String str = "Hello";
Class<String> c1 = String.class; // exact type token
Class<? extends String> c2 =
str.getClass(); // compiler magic
but this won't compile:
Class<? extends String> c3 =
Class.forName("java.lang.String"); // INVALID
Taking an unknown type token
Class<?>
and turning it into a type token
of a known type is a common action when working with reflection. What
you need is something that acts like a cast, but as you already know,
you can't perform casts involving parameterized types. The solution to
this is another piece of "magic" in the shape of the
asSubclass
method of
class
Class
:
public <T> Class<? extends T>
asSubclass(Class<T> subType)