虚拟机类加载机制

一、何时类应该被加载
类加载的包括七个阶段:加载,【验证,准备,解析】,初始化,使用,卸载。
而其中验证,准备,解析又统称为连接部分。不过java的类加载过程并不是严格按照这个顺序来执行的,其中解析阶段并
不一定会处在准备与初始化之间,java语言支持动态绑定,因此解析的过程变成了与其它阶段混合执行的阶段。
动态绑定也是对多态的支持。
那么什么时候类应该被加载?
当出现以下四种情况时,类会被加载以备使用:
(一)java程序要执行会去寻找入口方法main,因此含有执行入口main方法的类会被加载。
(二)当程序执行到与某个类直接相关的调用,那么这个类会被加载,如调用此类的类属性,类方法或是通过new关键字
来创建一个对象。
(三)当使用反射机制来调用某个类时,这个类若是未被加载,那么会对此类进行加载操作。反射操作中,我们通过可以
用Class clazz = Class.forName("className");然后再通过clazz来做到对这个类的方法和属性的调用。在进行这些操作之
前,类必须被加载到方法区,且在堆中有一个此类的Class类型的对象。如果没有,那么会触发类的加载行为。写过java连
mysql数据库的朋友都知道有这一句话:
Class.forName("com.mysql.jdbc.Driver");// 加载驱动程序
这句话显然是一种反射行为。因为JVM对java的语言的处理是只有当用到时才加载,连接数据库的包仅仅是加入到项目中并不
会引用相关类的加载行为。而这句话后面的注解是“加载驱动程序”原因是反射会引用类加载行为,以此来达到加载驱动的行为。
(四)当初始化一个类时,其父类未被加载,那么会先去加载父类。这个非常好理解,如果没有父类,子类是不能被完整构建
的,因此在构建子类时会先去构建父类。


二、类加载流程
1、加载
当程序执行到如:A a = new A();这样的语句时(这里的A代表类名),而A恰好没有加载到JVM中,那么将引起类加载行为。
最合理的作法是:根据类的全限定名(类A的完整类名)来找到对应的字节码文件,再将字节码文件导入JVM里。
因此加载过程只做三件事:
(一)根据类的全限定名找到对应的字节码文件
(二)将字节码文件里定义的结构转换成方法区里数据结构
(三)在java堆中生成一个A类的Class对象,做为反射时从堆对方法区的入口


2、验证
验证是一个庞大而复杂的过程,字节码文件所定义的每一个部分都会被验证,不光是确保后序执行过程中不会出因为格式或
是语法而引用的错误。而JVM做为一个庞大java系统运行的支持,它必须确保自身的安全性,才能更好地为用户程序服务。
具体的验证不再一一列出。


3、准备
这个阶段正式地为类属性分配内存并初始化它们。如private static String name = "zs";但这里的初始化并不会将name的
值初始化为"zs",而是会被初始化为系统默认的值null。至于何时为name赋值"zs",这个值会被类构造器统一收集,并在初始
化阶段为类变量赋值。


4、解析
解析过程是将符号引用换成直接引用,在字节码文件里,对字面量的引用对方法的引用都是符号引用,解析阶段需要将这个
过程转换成与内存布局相关的直接引用(相当于地址引用)。


5、初始化
在初始化阶段会执行类构造器<c1init>(),这个构造器会收集所有用户为类属性初始化的值,如:
public class Test{
private static int age = 18;
static{
age = 20;
}
}
构造器会收信息并进行统一的初始化工作,相当于:
c1init(){
age = 18;
age = 20;
}
因此当最后调用Test.age时这个值返回的是20。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值