Java如何查找标准库、第三方库及JRE中的.class文件?
嘿,这两个问题都是Java类加载机制里非常典型的困惑,我来给你拆解清楚:
一、Java如何查找标准库或第三方商业库的.class文件?
Java查找类文件是依靠类加载器层级和classpath共同作用的,分两种场景来说:
1. 标准库(JRE自带类)
JVM内置了一套类加载器体系,专门负责加载标准库,完全不需要你手动配置:
- Bootstrap类加载器:这是最顶层的加载器(用C++实现),负责加载JRE/lib目录下的核心类库(比如rt.jar里的
java.lang.String、java.util.ArrayList这些基础类)。 - Extension类加载器:负责加载JRE/lib/ext目录,或者通过
java.ext.dirs系统属性指定的扩展类库。
这些加载器的搜索路径是JVM默认内置的,不需要你在classpath里额外配置。
2. 第三方商业库(比如Spring、Apache Commons等)
这些类需要通过System类加载器(也叫应用类加载器)来加载,它的搜索范围就是你配置的classpath:
- 如果你手动运行程序,可以通过以下方式指定classpath:
- 设置系统环境变量
CLASSPATH,把第三方jar包路径或者class文件的根目录加进去; - 用
java命令的-cp或-classpath参数临时指定(推荐这种,避免环境变量冲突),比如:java -cp ./lib/CoolFramework.jar com.example.Main。
- 设置系统环境变量
- 如果你用Maven、Gradle这类构建工具,它们会自动把依赖的第三方库路径添加到运行时的classpath里,不用你手动管理。
另外,Java遵循双亲委派模型:当要加载一个类时,会先让父加载器尝试加载,只有父加载器找不到,当前加载器才会自己去搜索。这就保证了标准库的类不会被第三方类篡改。
二、为什么JRE自带库不需要在classpath里也能被找到?
你之前了解的classpath,其实只是System类加载器的搜索范围,而JRE自带的核心类是由更上层的Bootstrap和Extension加载器负责的,它们的搜索路径和classpath完全是两回事:
类加载器的职责划分:
- Bootstrap和Extension加载器负责JVM自身的核心类,它们的搜索路径是JVM启动时就内置好的(比如
sun.boot.class.path这个系统属性就记录了Bootstrap的加载路径); - System加载器才负责加载你自己写的代码和第三方库,它的搜索路径就是你配置的classpath(对应系统属性
java.class.path)。
- Bootstrap和Extension加载器负责JVM自身的核心类,它们的搜索路径是JVM启动时就内置好的(比如
双亲委派机制的作用:
比如当你的代码要用到java.lang.String时,首先会委托给System类加载器的父加载器——Extension加载器,Extension再委托给Bootstrap加载器,Bootstrap会从rt.jar里找到这个类并加载,根本不会去搜索classpath。只有当加载的是你自己写的com.example.MyClass或者第三方库的类时,才会走到System加载器,去classpath里查找。
你可以试试在命令行运行java -XshowSettings:properties,就能看到这些和类加载路径相关的系统属性,一目了然。
内容的提问来源于stack exchange,提问作者user12394078

