image.png

1. 什么叫做类加载?

JVM把描述类的数据从Class文件加载到内存, 并对数据进行校验、 转换解析和初始化, 最终形成可以被虚拟机直接使用的Java类型, 这个过程被称作虚拟机的类加载机制。

2. 类加载的时机

程序代码中用到这个类的时候

3. 类加载的过程

3.1 加载-loading

加载class文件字节流到方法区中,并在堆内存中生成一个代表这个类的Class对象,相当于该对象的元数据。

3.2 连接-linking

验证

校验加载的class文件是否符合JVM规范

准备

静态变量赋默认值

解析

3.3 初始化-initialization

javac编译器自动收集类中所有类变量的赋值动作和静态代码块中的语句合并来的

执行static变量的显示赋值和static代码块,执行顺序和代码中声明顺序一致

先初始化父类,再初始化子类

4. 类加载器

4.1 类加载器的分类

启动类加载器

一旦你的JVM启动,那么首先就会依托启动类加载器,去加载你的Java安装目录下的“lib”目录中的核心类库

加载jre/lib目录下的核心类库

扩展类加载器

加载jre/lib/ext目录下的扩展类库

应用程序类加载器

加载classpath环境变量路径下的类,可以理解为加载我们自己写的类

自定义类加载器

可以自定义类加载器,继承ClassLoader

4.2 双亲委派

类加载器是有亲子层级关系的

先找父亲去加载,不行的话再由儿子来加载

  1. protected Class<?> loadClass(String name, boolean resolve)
  2. throws ClassNotFoundException
  3. {
  4. synchronized (getClassLoadingLock(name)) {
  5. // First, check if the class has already been loaded
  6. Class<?> c = findLoadedClass(name);
  7. if (c == null) {
  8. long t0 = System.nanoTime();
  9. try {
  10. if (parent != null) {
  11. c = parent.loadClass(name, false);
  12. } else {
  13. c = findBootstrapClassOrNull(name);
  14. }
  15. } catch (ClassNotFoundException e) {
  16. // ClassNotFoundException thrown if class not found
  17. // from the non-null parent class loader
  18. }
  19. if (c == null) {
  20. // If still not found, then invoke findClass in order
  21. // to find the class.
  22. long t1 = System.nanoTime();
  23. c = findClass(name);
  24. }
  25. }
  26. if (resolve) {
  27. resolveClass(c);
  28. }
  29. return c;
  30. }
  31. }

4.3 为什么是双亲委派

避免重复加载