一.什么是类加载
Java中,每一个类或者接口,在经历编译器后,都会生成一个个.class文件。.class文件(编译.java程序生成的源代码文件)的加载运行需经过:加载、验证、准备、解析、初始化,五个过程。
二.加载
什么时候加载
使用new实例化对象时、读取或者设置一个类的静态字段或方法时
反射调用时,例如 Class.forName("com.xxx.Hello")
三.验证
主要是校验.class文件的合法性,涉及到jvm安全性的问题 ,比如说final类有没有被继承,包括限定修饰符的判断。
四.准备
准备阶段的主要任务是为类的静态变量开辟空间并赋默认值
五.解析
这个阶段,虚拟机会把这个Class文件中,常量池内的符号引用转换为直接引用。主要解析的是 类或接口、字段、类方法、接口方法、方法类型、方法句柄等符号引用。我们可以把解析阶段中,符号引用转换为直接引用的过程,理解为当前加载的这个类,和它所引用的类,正式进行“连接“的过程。
六.初始化
这是类加载的最后一个步骤啦,初始化的过程,就是执行类构造器 <clinit>()方法的过程。 当初始化完成之后,类中static修饰的变量会赋予程序员实际定义的“值”,同时类中如果存在static代码块,也会执行这个静态代码块里面的代码。
七.类加载器
1.什么是类加载器
类加载器是在加载阶段,通过类的全限定名,获取该类字节流数据。
2.类加载器介绍
启动类加载器(BootstrapClassLoader):负责加载<JAVA_HOME>\lib 目录,或者被 -Xbootclasspath 参数制定的路径,例如 jre/lib/rt.jar 里所有的class文件。由C++实现,不是ClassLoader子类。
拓展类加载器(ExtClassLoader):负责加载Java平台中扩展功能的一些jar包,包括<JAVA_HOME>\lib\ext 目录中 或 java.ext.dirs 指定目录下的jar包。由Java代码实现。
应用程序类加载器(AppClassLoader):我们自己开发的应用程序,就是由它进行加载的,负责加载ClassPath路径下所有jar包。
3.双亲委派机制
双亲委派机制主要是存在与咱们的类加载过程中,在我们加载一个类的时候,不会直接去调用当前类所在作用域的类加载器,而是向上委派给父类加载器去加载,当父类加载器不能加载时,再向下交给我们当前类加载器加载。
根据下图我们可以发现,像String、L;ist这类都是被BootstrapClassLoader加载器加载的,因为他是用c/c++编译的,所以java识别不出来,因此会显示null。而我们自定义的Hello类,加载器是AppClassLoader,他的父类是ExtClassLoader,父类的父类是BootstrapClassLoader。
4.双亲委派机制的好处:
安全性强,
如下图,我们自己定义了一个java.lang.String类,这时候加载的话是启动类加载器来加载的,而自己写的这个String类就不会覆盖我们启动类加载器下的核心类库中的java.lang.String类,从而保证了我们的一个安全性。
八.为什么java配置的环境变量指向lib文件夹
lib下面所有的类都可以扫描到,一些类是在商业化开发时是有用到的