【JVM】类加载器
加载-->验证-->准备-->解析-->初始化--->使用-->卸载
jvm会在程序使用到某个类的时候通过类加载器将其加载jvm,当然是main方法开始的。
验证,根据Java的虚拟机规范来校验加载进来的 .class文件是否符合规范。
准备,给类变量等分配一些内存空间及初始化值,各种各样的零
解析,把符号引用替换为直接引用
加载一个类的时候必须要先加载并初始化他的父类。
类加载器
类加载器是通过类的全限定名(或者说绝对路径)来找到一个class文件的。宏观来看,只有两种类加载器:启动类加载器、其他类加载器。启动类加载器属于虚拟机的一部分,它是用C++写的,看不到源码;其他类加载器是用Java写的,说白了就是一些Java类,比如扩展类加载器、应用类加载器。不同的类库可能是被不同的类加载器加载的。
类加载器是有层级结构的,第一层是启动类加载器,第二层是扩展类加载器,第三层是应用程序类加载器,最后是自定义类加载器。可以看作父子关系
启动类加载器:bootstrap classLoad,用于加载jdk的lib目录下的核心类库。
扩展类加载器:extension classLoad,用于加载lib\ext目录下的类库。
应用程序类加载器:application classLoad,负责加载自己些的类到内存中。
自定义类加载器:可以自己编写类加载器,根据需求加载自己的类。
双亲委派机制
自己写的类一般都是由应用程序类加载器加载的,他拿到这个类不会马上就加载,会给自己的上一级扩展类加载器,而扩展类加载器也不会马上加载,会再给自己的上级启动类加载器。当启动类加载器在自己负责加载的范围内没有找到这个类时就会再给自己的下一级扩展类加载器去加载,这是扩展类加载器就会看自己负责的范围内有没有这个类,如果没有就再给他的下级应用程序类加载器去加载,应用程序类加载器找到了就会去加载了。
双亲委派机制的作用
确保类的全局唯一性。
如果你自己写的一个类与核心类库中的类重名,会发现这个类可以被正常编译,但永远无法被加载运行。因为你写的这个类不会被应用类加载器加载,而是被委托到顶层,被启动类加载器在核心类库中找到了。如果没有双亲委托机制来确保类的全局唯一性,谁都可以编写一个java.lang.Object类放在classpath下,那应用程序就乱套了。从安全的角度讲,通过双亲委托机制,Java虚拟机总是先从最可信的Java核心API查找类型,可以防止不可信的类假扮被信任的类对系统造成危害。