一个 Java 项目启动时,JVM 会加载一系列类,这些类主要分为以下几类:
启动类加载器(Bootstrap ClassLoader)加载的核心类库:
- 这些是 JVM 运行所必需的最基础的类,通常位于
$JAVA_HOME/lib目录下,例如rt.jar、resources.jar、charsets.jar等。 - 包括
java.lang.Object、java.lang.String、java.lang.Class等核心 Java 类。 - 这些类由 C++ 实现的启动类加载器加载,是 JVM 自身的一部分。
- 这些是 JVM 运行所必需的最基础的类,通常位于
扩展类加载器(Extension ClassLoader)加载的扩展类库:
- 这些类通常位于
$JAVA_HOME/lib/ext目录下,或者由系统属性java.ext.dirs指定的路径中。 - 例如,一些 Java 扩展功能的实现类。
- 这些类通常位于
应用程序类加载器(Application ClassLoader)加载的用户类:
- 这是默认的类加载器,负责加载用户类路径(Classpath)上的类库。
- 这包括用户自己编写的代码(如
HelloWorld类)以及项目依赖的第三方库(JAR 包)。 - 当执行
java HelloWorld命令时,JVM 会首先通过应用程序类加载器加载HelloWorld类。
主类(Main Class)的加载与初始化:
- JVM 启动时,会根据命令行指定的主类(例如
HelloWorld)进行加载。 - 加载过程遵循双亲委派模型,即先由启动类加载器加载,如果加载不到,再由扩展类加载器加载,最后由应用程序类加载器加载。
- 在加载
HelloWorld类时,会先初始化其父类(如果有的话),然后才初始化HelloWorld类本身。
- JVM 启动时,会根据命令行指定的主类(例如
其他可能被加载的类:
- 在程序运行过程中,如果需要使用其他类(如通过反射调用
Class.forName()),JVM 会在需要时加载这些类,并遵循类加载器的层次结构和双亲委派模型。 - 如果程序使用了 SPI(Service Provider Interface)机制(例如 JDBC 驱动加载),可能会涉及到线程上下文类加载器来加载特定的实现类,这可能会绕过标准的双亲委派模型。
- 在程序运行过程中,如果需要使用其他类(如通过反射调用
总的来说,JVM 启动时会首先加载核心的 Java 类库(由启动类加载器加载),然后加载扩展库(由扩展类加载器加载),最后加载用户自己的类(由应用程序类加载器加载)。这个过程确保了 Java 程序运行的基础环境和用户代码的正确加载与初始化。
开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明一个java项目启动时,JVM会加载哪些类?!

