先上图:
类加载器ClassLoader:
classLoader作为一个运输工具存在,将本地硬盘/网络class文件以流的形式加载到JVM的方法区中,形成DNA元数据模板--即方法区(JDK8.0的元数据区)。
注意点:字符串常量池和静态变量存放在堆中,这个可以查看JVM--方法区文档。
类加载器种类:
引导类加载器(BootstapClassLoader):C语言编写吗,加载核心库
扩展类加载器(ExtClassLoader):加载扩展目录下的类库
系统类加载器(SystemClassLoader):应用的类一般都有此加载器加载。
自定义加载器:作为一个扩展的存在。
类加载器之间的关系:不是上下级的父子关系,而是包含关系,比如ExtClassLoader包含BootstapClasLoader对象。
为什么要这个处理加载器?这牵扯到了双亲委派机制。
双亲委派机制:起保护作用,防止java核心库类被覆盖
Java虚拟机对class文件是按需加载的方式,采用的就是双亲委派模式,即把请求交由父类处理,是一种任务委派模式。
工作原理:
先一直向上委托直到引导类加载器,若上方加载器无法加载,则向下交由子加载器尝试加载,一旦加载到类就成功返回。
双亲委派机制的优势:
避免类的重复加载
保护程序安全,防止核心API被随意篡改。
加载的三个步骤:
1、Loading(加载)
生成的Class对象,是保存在堆中的,它也是个对象,通过它能关联上方法区中的所有信息,这也是反射的原理。Class类中有个ForName(String className),能通过路径获取到相应的Class对象,再通过Class对象获取生成对象或获取相应对象的属性,方法等等。
2、Linking(链接)
- 验证:校验字节码文件是否合法。
- 准备:为类变量(除final static 修改的变量外)分配空间,并给出默认值。
- 解析:将符号引用转为直接引用。
3、Initialization(初始化)
类构造器方法(clinit)--这个是编译时自动生成的方法(存放静态变量和静态代码块,执行时按源文件中出现的顺序执行)
类的构造器方法(init)--就是我们常说的构造方法,是虚拟机视角下的定义。
这有个非法的前向引用,没弄懂,有清楚的朋友能留个言吗?多谢多谢!
类的其他说明:
同类的判断:完整类名+classLoader
类的主动加载和被动加载:
区别:被动加载不会执行初始化步骤