一.看前须知
1.jvm会校验class文件的完整性和准确性,然后加载到内存里.
2.那么靠谁来加载呢?就是类加载器classloader
3.classloader的定义:JVM加载class文件的工具.
4.同一个包类名且同一个类加载器加载的,是同一个类.(这意味着使用不同的加载器来加载同一个class文件,那就不是同一个类,我们会在后面去验证这个道理.),
二.ClassLoader分类
直接贴图
三.几个疑问
- 我们怎么获得类加载器?
- BootStrapClassLoader究竟是什么?
- 应用程序加载器的ClassPath是什么?
- 如果我把自己写的jar包,放到拓展包目录下,那么它的加载器是什么?
- 自定义类加载器我们该如何使用?
- 同一个class文件被不同的classloader去加载得到的类是一样的吗?
- 类加载器在我们平时写代码时有什么用?
四.探究疑问之我们怎么获得类加载器
怎么获得类加载器?其实是有现成的方法的.
随便写个类 执行下面这个main方法
public class Girl { public static void main(String[] args) { System.out.println(Girl.class.getClassLoader().toString()); } }
结果:
sun.misc.Launcher$AppClassLoader@73d16e93
我们可以看到这个类加载器的是AppClassLoader.正是上面那个图片里第三级的classLoader
对的.如何获得classLoader呢?就是通过Class.getClassLoader这个方法来获得的.
五.探究疑问之BootStrapClassLoader究竟是什么?
在图上可以看到BootStrapClassLoader是加载String ,System这些核心类的加载器.咱们可以试一下.
public class Girl { public static void main(String[] args) { System.out.println(String.class.getClassLoader()); } }
运行结果是个null,竟然是个null.为什么会这样呢?原来BootStrapClassLoader根本就不是个JAVA对象,它是用C++编写的.整个JVM都是用C++编写的.然后又编写了个加载核心类的工具就是BootStrapClassLoader.所以我们才获取不到它.但它无处不在.
那么它加载的核心组件是什么呢?
打开我们的jdk,如图
就是加载这些核心组件.但是里面那个ext那个文件夹要注意,那里面不是BootStrapClassLoader加载的,而是拓展类库加载的.
六.探究疑问之应用程序加载器的ClassPath是什么?
其实就是字面意思,class文件的path,就是class文件的系统路径,系统要是想加载什么东西,那必须得有这个东西的资源定位符啊.
环境变量里的ClassPath就是java.exe执行命令的时候,到哪里去找class文件,切记:并不会去当前目录去找,而是去配置的地方去找,如果想要到当前目录,那么需要在CLASSPTAH这个里面多配置一个点"."
Tomcat里的classpath略有不同,tomcat启动时会把系统的classpath给清空掉,设定几个自己的classpath,其中有两个就是WEB-INF/lib和WEB-INF/classes.
那么个人推测,MyEclipse做的和Tomcat一样,在普通java项目里会动态把classPath设置为项目下的bin包.这样才可以加载.
七.探究疑问之如果我把自己写的jar包,放到拓展包目录下,那么它的加载器是什么?