Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is meant by "the erasure of the static type of the expression on which it is called" in the getClass() docs?

Tags:

java

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?

like image 986
Scooter Avatar asked Oct 12 '13 09:10

Scooter


2 Answers

The Java Language Specification mandates that this method is treated in a special way by the compiler:

The method getClass returns the Class 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|> where T 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 type T. 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>>.

like image 184
meriton Avatar answered Nov 13 '22 22:11

meriton


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>.

like image 23
Katona Avatar answered Nov 14 '22 00:11

Katona