The documentation for the "public final Class<?> getClass()" method of Object says:
The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:
I don't understand the explanation, particularly with regard to what |X| is said to be - "the erasure of the static type of the expression on which getClass is called".
What form of notation is |X| ? Or maybe, where else would |X| type notation be used?
The Java Language Specification mandates that this method is treated in a special way by the compiler:
The method
getClass
returns theClass
object that represents the class of the object.A
Class
object exists for each reference type. It can be used, for example, to discover the fully qualified name of a class, its members, its immediate superclass, and any interfaces that it implements.The type of a method invocation expression of getClass is
Class<? extends |T|>
whereT
is the class or interface searched (§15.12.1) for getClass.
So the return type of getClass is the static (compile-time) type of the expression getClass()
is invoked on. For instance:
String s = "";
Object o = s;
Class<? extends String> sc = s.getClass(); // ok
Class<? extends Object> oc = o.getClass(); // ok
oc = sc; // ok
sc = o.getClass(); // not ok
sc = oc; // not ok
The notation |X|
is defined in spec as follows:
Type erasure is a mapping from types (possibly including parameterized types and type variables) to types (that are never parameterized types or type variables). We write
|T|
for the erasure of typeT
. The erasure mapping is defined as follows:
The erasure of a parameterized type (§4.5)
G<T1,...,Tn>
is|G|
.The erasure of a nested type
T.C
is|T|.C
.The erasure of an array type
T[]
is|T|[]
.The erasure of a type variable (§4.4) is the erasure of its leftmost bound.
The erasure of every other type is the type itself.
For instance, if we have:
List<String> list = ...;
the expression list.getClass()
is of type Class<? extends List>
rather than Class<? extends List<String>>
.
Let's consider the following example:
List<Integer> test = new ArrayList<Integer>();
Class<? extends List> clazz = test.getClass();
the static type of test
(the expression on which getClass() is called
) is List<Integer>
of which the erasure is List
(see type erasure). Note that the dynamic (or runtime) type of test
is ArrayList
, and the runtime type of clazz
will be Class<ArrayList>
.
So, Class<? extends |X|>
in this case is Class<? extends List>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With