我们编写好的Java程序都是由若干个class文件组织而成。当我们程序运行时,会调用该程序的一个入口函数来执行程序功能,而这些功能是封装在不同的class文件中的,所以就常常会从这个class文件调用另一个class文件中的方法。如果另外一个class文件不存在,就会引发系统异常。
< div> 我们编写好的Java程序都是由若干个class文件组织而成。当我们程序运行时,会调用该程序的一个入口函数来执行程序功能,而这些功能是封装在不同的class文件中的,所以就常常会从这个class文件调用另一个class文件中的方法。如果另外一个class文件不存在,就会引发系统异常。 程序在启动时,绝对不会加载程序需要的所有class文件,而是根据程序需要,通过Java的类加载机制来动态地加载某一个class文件到内存当中。 类加载器在Java中非常重要,下面从如下几个方面来进行讲解。 二、什么是类加载器? ClassLoader就是用来动态加载class文件到内存当中的。 三、类加载器的类型 1、从开发者角度划分: (1)BootStrap ClassLoader 启动类的加载器,负责加载放在JDK中li目录下的文件。 (2)Extension ClassLoader 扩展类的加载器,负责加载JRE中ext目录下的文件。 (3)App ClassLoader 应用程序类加载器,负责加载用户路径下指定的类。 2、从 虚拟机角度划分: (1)启动类加载器(C++语言实现) (2)所有其他类加载器(Java语言实现) 四、双亲委派模型 每一层类加载器上方的类加载器叫作父类加载器。它们之间的父子关系不是通过继承来实现的,而是使用组合关系来复用父类加载器中的代码。 当类加载器需要加载一个class文件时,首先先请求父类加载器去加载,只有当所有父类加载器没有找到对应的类时,才会自己去加载。 双亲委派模型对于保护Java程序的稳定性非常重要。 五、类加载过程(加载-->卸载) 1、静态绑定、动态绑定 2、第一步:加载 (1)通过一个类的全限定名来获取其定义的二进制字节流 (2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 (3)在Java堆中生成一个代表这个类的lang .lang.Class对象,作为对方法区中的这些数据的访问入口 3、第二步:验证 为了确保class文件中的字节流包含的信息符合当前虚拟机的要求 4、第三步:准备 正式为类变量分配内存,并设置类变量初始化。 这些内存是在方法区中分配的。 (1)同时被static和final修饰的变量必须在声明的时候就赋值 (2)数组初始化时,默认值为null,其中元素也被相应赋上默认值 5、第四步:解析 6、第五步:初始化 执行类构造方法的过程(注意:成员变量初始化在准备阶段就完成了