无法理解Class对象

Kar*_*tic 7 java multithreading class synchronized

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

您可能想知道在调用静态同步方法时会发生什么,因为静态方法与类关联,而不是与对象关联.在这种情况下,线程获取与该类关联的Class对象的内部锁.因此,对类的静态字段的访问由与该类的任何实例的锁不同的锁控制.

我并没有完全理解这个概念Class object.在了解了一些在线内容后,我了解到:

Class对象是一种描述对象类的元对象,如名称,包等.

我的问题是:

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

有一个类似的问题是java中的Class Object(java.lang.class).但它没有回答我的问题.

[更新]

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

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

man*_*uti 9

1.什么时候创建?

它是在JVM使用类加载器加载类时创建的.当某个类被其他类引用时,将加载该类.A ClassLoader通常Class在调用时创建此实例ClassLoader#loadClass(String className).这在Java语言规范的链接中有解释:

加载是指查找具有特定名称的类或接口类型的二进制形式的过程,可能是通过动态计算,但更典型的是通过检索先前由Java编译器从源代码计算的二进制表示,并构造,从该二进制形式,一个Class表示类或接口的对象.

2.在某个时间点收集垃圾吗?

与任何其他实例一样,如果Class实例不再可访问,则它符合GC的条件.当没有Class实例表示的类型的对象可访问时,会发生这种情况,并且加载该类的类加载器也不可访问.

3.由于它是由synchronized static方法使用的,它是否意味着每个JVM只有一个Class对象的实例?

不必要.如果您定义了一个自定义类加载器,那么您可以有两个a实例Class.在这种情况下,ClassCastException如果您尝试将某个类的对象转换A为"相同类型"(A如果它们由两个不同的类加载器加载),您甚至可能会得到一个.