JVM,众所周知乃是java的根
~ 为什么要学习这个呢,当然是我爱学习了(应付面试的,毕竟面试造航母,工作拧螺丝);
开撸,先来张图 跟着狂神学java
大致上如此,当然还会有再细化的。
类加载器
众所周知,在面向对象是就听过一句话,类是对象的模板。
在jvm中有四种类加载器,它们有层级之分,先看第一种。
public class Student {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student.getClass().getClassLoader());// 查看类加载器
}
}
sun.misc.Launcher$AppClassLoader@18b4aac2
看着个AppClassLoader,这就是一个类加载器,也叫应用程序加载器,也是我们最常使用的。
来再看下它的父类加载器
public class Student {
public static void main(String[] args) {
Student student = new Student();
// 1
System.out.println(student.getClass().getClassLoader());
// 2
ClassLoader classLoader = student.getClass().getClassLoader();
ClassLoader parent = classLoader.getParent();
System.out.println(parent);
// 3
System.out.println(parent.getParent());
}
}
运行 go!
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@2a84aee7 // 出现第二种加载器
null // 咦,这个怎么是null
解释一下吧,四种加载器,它们并不是继承关系。
- App ,应用程序加载器级别最小的。
- Ext ,扩展类加载器,这个ext包就是啦。
- B00T ,启动类加载器,也叫根加载器。
- 用户自定义加载器。
为什么第三种会为null呢,据说java最早是叫C++--,它就是解决C++里繁琐的指针,和操作内存,所以说那两个底层还是用C写的,用java肯定get不到了。
双亲委派
总结一句话,向上委派,向下查找。
借用一下别人画的图和解释
原文链接:https://blog.csdn.net/codeyanbao/article/details/82875064
当一个Hello.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理也会先检查自己是否已经加载过,如果没有再往上。注意这个类似递归的过程,直到到达Bootstrap classLoader之前,都是在检查是否加载过,并不会选择自己去加载。直到BootstrapClassLoader,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。