**
类是在运行期间第一次使用时动态加载的,而不是编译时期一次性加载。因为如果在编译时期 一次性加载,那么会占用很多的内存。
**
类加载包括以下 7 个阶段:
加载(Loading)
验证(Verification)
准备(Preparation)
解析(Resolution)
初始化(Initialization)
-
加载
加载是类加载的一个阶段,注意不要混淆。
加载过程完成以下三件事:
通过一个类的全限定名来获取定义此类的二进制字节流。
将这个字节流所代表的静态存储结构转化为方法区的运行时存储结构。
在内存中生成一个代表这个类的 Class 对象,作为方法区这个类的各种数据的访问入口。
其中二进制字节流可以从以下方式中获取:
从 ZIP 包读取,成为 JAR、EAR、WAR 格式的基础。
从网络中获取,最典型的应用是 Applet。
运行时计算生成,例如动态代理技术,在 java.lang.reflect.Proxy 使用
ProxyGenerator.generateProxyClass 的代理类的二进制字节流。
由其他文件生成,例如由 JSP 文件生成对应的 Class 类。 -
验证
.确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安
全。 -
准备
类变量是被 static 修饰的变量,准备阶段为类变量分配内存并设置初始值,使用的是方法区的
内存。
实例变量不会在这阶段分配内存,它将会在对象实例化时随着对象一起分配在堆中。
注意,实例化不是类加载的一个过程,类加载发生在所有实例化操作之前,并且类加载只进行
一次,实例化可以进行多次。 -
解析
将常量池的符号引用替换为直接引用的过程。
其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。 -
初始化
初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段即虚拟机执行类构造器
() 方法的过程。
在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序
制定的主观计划去初始化类变量和其它资源。