This question touches on two topics. The first one is
the Class class in general.
Instances of
Class<T> represent the runtime description of types. In these terms, enumerations are treated as classes, and annotations as interfaces. These
metaclasses are mostly interacted with during reflection or when working with class loaders.
Mostly, instances of the
Class class consist of content from the .class file and are created only inside a class loader. The details of storing them in memory are discussed in the
previous post.
The second topic here concerns the peculiarities of the
Class for primitives, arrays, and void. To obtain instances for these, the same syntax is used as for regular classes:
void.class,
int.class,
float[][].class. The
foo.class structure is not an access to a member but a
class literal.
For
void, the type parameter
T is the special uninstantiable type
java.lang.Void. The type parameter for a primitive is the corresponding
wrapper class. However, the wrapper class itself will have a separate
Class instance, meaning
int.class != Integer.class.
The
getClassLoader method for a regular class or interface returns the loader that loaded it.
null may be returned for types loaded by the bootstrap class loader. For an array, it returns the same as for the type of its elements. For primitives and
void, the result will always be
null.