类的生命周期

一个类在使用前,Java虚拟机一般要确保该类已经被加载,连接(包括验证,准备,解析)和初始化,这些步骤都是严格按顺序执行的
加载:查找并把类的二进制数据加载到内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构;
连接:把已经加载到内存中的类的二进制数据合并到虚拟机的运行时环境中去,包括验证,准备,解析类的二进制数据,验证主要是确保被加载类的准确性;准备主要是为类的静态变量分配内存,并初始化为默认值;解析则把类中的符号引用转换为直接引用;
初始化:给类的静态变量赋予正确的初始值;(通常只有当我们首次主动使用该类或接口时才进行这一步);
接下来谈谈类加载器,因为类的加载主要由它来完成的,类加载器可分为两种:
Java虚拟机自带的加载器,包括启动类加载器,扩展类加载器和系统类加载器;
用户自定义的类加载器,是java.lang.ClassLoader类的子类的实例,用户可以通过它来定制类的加载方式。
类加载器并不需要等到某个类被首次主动使用时再加载它,Java虚拟机规范允许类加载器在预料某个类将要被使用时就预先加载它如果在加载过程中遇到.class文件缺失或存在错误,类加载器必须等到程序首次主动使用该类的时候才报告错误。
类的验证主要报错几个方面的检查:
类文件的结构检查:保证类文件遵从java类文件的固定格式;
语义检查:确保类本身符合java语言的语法规定;
字节码验证:字节码代表nava方法,它是由被称为操作码的单字节指令组成的序列,每一个操作码后面都跟着一个或多个操作数;
二进制兼容的验证:确保相互引用的类之间协调一致;
类的准备和解析阶段前面也说得很清楚了就不在详细说了。
类的初始化的步骤:
假设这个类还没有被加载和连接,那就先进行加载和连接;
假如存在直接的父类,并且这个父类还没有被初始化,那就先初始化直接的父类;
假如类中存在初始化语句,那就按顺序执行这些初始化语句。
前面提到对类的主动使用,只有主动使用时才会导致类的初始化,下面总结下主动使用的方式:
创建类的实例;
调用类的静态方法;
访问某个类或接口的静态变量,或者对该静态变量赋初值;
初始化一个类的子类;
Java虚拟机启动时被标明为启动类的类。所谓标志为启动类的类就是相当于在cmd下输入java Test类似的,Test即启动类。
对于final类型的静态变量,如果在编译时能计算出变量的取值,那么这种变量被看做编译时常量。java程序中对类的编译时常量的使用,被看做时对类的被动使用,不会导致类的初始化。
当java虚拟机初始化一个类时,要求它的所有父类都已经被初始化,但是这条规则并不适用于接口。只有当程序首次使用特定接口的静态变量时,才会导致该接口的初始化。
调用ClassLoader类的loadClass()方法加载一个类,并不是对类的主动使用,不会导致类的初始化。


[align=center][size=xx-large;]欢迎大家光临我的个人Java+Flex博客[b][url=http://nijiaben058.jspkj.com]http://nijiaben058.jspkj.com[/url][/b][/size][/align]

你可能感兴趣的:(java)