无法理解 Class 个对象

Unable to understand Class object

Oracle Java 关于内部锁和同步的文档说:

You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.

我没有完全理解Class object的概念。在学习了一些在线内容后,我了解到:

A Class object is sort of a meta object describing the class of an object such as name, package etc.

我的问题是:

  1. 什么时候创建的?
  2. 是否在某个时间点收集了垃圾?
  3. 由于它被同步静态方法使用,是否意味着每个 JVM 将只有一个 Class 对象实例?

有一个类似的问题what is Class Object(java.lang.class) in java。但它没有回答我的问题。

[更新]

manouti 提供的答案的评论部分添加了一个新问题,因为他提到 Class 对象可以有多个实例:

  1. 如果存在 Class 对象的多个实例,是否有可能多个线程同时访问静态同步方法?
  1. 来自 Class 上的 JavaDocs:

Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.

  1. 只要 class 的实例在使用中并且对 Class 对象的引用持续存在,它就会保留在内存中。

  2. 是的。 Class 是不可变的,因此没有真正的同步问题。

1。什么时候创建的?

它是在 JVM 使用 classloader 加载 class 时创建的。 class 在被其他 class 引用时被加载。 ClassLoader 通常在调用 ClassLoader#loadClass(String className). This is explained in this link from the Java Language Specification:

时创建此 Class 实例

Loading refers to the process of finding the binary form of a class or interface type with a particular name, perhaps by computing it on the fly, but more typically by retrieving a binary representation previously computed from source code by a Java compiler, and constructing, from that binary form, a Class object to represent the class or interface.

2。是否在某个时间点收集了垃圾?

就像任何其他实例一样,如果 Class 实例不再可访问,它就有资格进行 GC。当 Class 实例表示的类型的对象不可访问且加载 class 的 classloader 也不可访问时,会发生这种情况。

3。由于它由同步静态方法使用,是否意味着每个 JVM 将只有一个 Class 对象实例?

不一定。如果您定义一个自定义 classloader,那么您可以有一个 Class 的两个实例。在这种情况下,如果您尝试将某个 class A 的对象转换为“相同类型” A 如果它们已加载,您甚至可能会得到 ClassCastException通过两个不同的 classloader。