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
getClassreturns theClassobject that represents the class of the object.A
Classobject 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|>whereTis 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.Cis|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