类的加载
目标
- 能够理解字节码加载过程 【了解】
路径
- 类的加载过程
- 类的加载时机
类的加载
- 当程序在运行后,第一次使用某个类的时候,会将此类的class文件读取到内存,并将此类的所有信息存储到一个Class对象中
说明:Class对象是指java.lang.Class类的对象,此类由Java类库提供,专门用于存储类型的信息
在以下情况下会加载类:
- 创建一个类的对象(第1次)
- 调用类的静态方法,静态变量 (第1次)
- 使用一个类的子类时 (第1次)
- 通过反射进行加载类
- java命令执行某一个类 (第1次)运行java程序
public class HelloWorld{public static void main(String[] args){System.out.println("Hello World!");}
}//编译: javac HelloWorld.java //生成:HelloWorld.class 字节码文件
//运行: Java HelloWorld //使用java命令执行HelloWorld类(默认调用main方法)//底层: HelloWorld.main(null);
问题1:Student.class文件中都包含什么内容?
- 构造方法、成员变量、成员方法
在jvm执行某个类时,如果该类是第一次被执行:
- 先把该类的.class文件读取到内存中
- 基于.class文件创建一个Class对象(方法区)
- Class对象中存储的是.class文件中的内容:构造方法、成员变量、成员方法
- Class对象中存储的构造方法:构造器对象 Constructor对象
- Class对象中存储的成员方法:方法对象 Method对象
- Class对象中存储的成员变量:字段对象 Field对象
类加载器
类加载器的作用
什么是类加载器?
- 加载器是Java运行时环境的一部分,负责加载字节码文件
类加载器的作用:
- 负责将磁盘上的某个class文件读取到内存并生成Class的对象
Java中有三种类加载器,它们分别用于加载不同种类的class:
- 启动类加载器(Bootstrap ClassLoader):用于加载系统类库\bin目录下的class,例如:rt.jar。
- 扩展类加载器(Extension ClassLoader):用于加载扩展类库\lib\ext目录下的class。
- 应用程序类加载器(Application ClassLoader):用于加载我们自定义类的加载器
获取类加载器的方式
来自Class类型获取类加载器的方法:
public ClassLoader getClassLoader() //返回该类的类加载器
//有些实现可能使用null来表示引导类加载器(启动类加载器)
//如果该类由引导类加载器(启动类加载器)加载,则此方法在这类实现中将返回 null
代码实践:
//自定义类型
class Student{private int age;
}//测试类
public class Demo01 {public static void main(String[] args){//获取自定义类的类加载器//1. 先获取Student对应的Class对象Class<Student> cls = Student.class; //2. 再通过该class对象获取类加载器ClassLoader loader = cls.getClassLoader();System.out.println("loader = "+loader);//ClassLoaders$AppClassLoader@2437c6dc//获取String类的类加载器ClassLoader loader2 = String.class.getClassLoader();System.out.println("loader2 = " + loader2);}
}
小结
类加载器的作用:
- 把硬盘上的.class文件读取到内存中并创建Class对象
类加载器可以分为3种:
- 引导类加载器(启动类加载器) 负载加载系统类库(java.lang包)
- 扩展类加载器 负责加载jdk扩展的类库
- 应用程序类加载器 负责加载程序员自己写的类
双亲委派机制
路径
- 3种类加载器的关系
- 双亲委派机制
- 双亲委派机制的好处
从上图可知,三种类加载器存在一定的关系:
- 应用程序类加载器的父级类加器是扩展类加载器
- 扩展类加载器的父级类加载器是启动类加载器
结论:这种关系称为类加载器的"双亲委派模型"
"双亲委派模型"的工作机制:
- 某个"类加载器"收到类加载的请求,它首先不会尝试自己去加载这个类,而是把请求交给父级类加载器
- 因此,所有的类加载的请求最终都会传送到顶层的"启动类加载器"中
- 如果"父级类加载器"无法加载这个类,然后子级类加载器再去加载
"双亲委派模型"中,除了顶层的启动类加载器外,其余的类加载器都应当有自己的"父级类加载器"
小结
双亲委派机制:
- 在使用一个类时,类并不会由应用程序类加载器来加载,而是由"双亲:启动类加载器、扩展类加载器"先来进行加载,当"双亲"无法加载时,才由应用程序类加载器来完成.class的加载及Class对象的创建