Java 类加载基本过程详细介绍
这里有新鲜出炉的 Java 并发编程示例, 程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言, 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台 (即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)) 的总称
这篇文章主要介绍了 Java 类加载基本过程详细介绍的相关资料, 需要的朋友可以参考下
Java 类加载基本过程详细介绍
基本过程:
根据类的全限定名称加载定义类的二进制字节流
将字节流代表的静态存储结构转化为方法区的运行时数据结构
内存中生成一个代表这个类的 java.lang.Class 对象, 作为方法去这个类的各种数据访问入口
数组类本身不通过类加载器创建, 由 java 虚拟机直接创建, 数组类的元素类型由类加载器加载
数组类的元素类型: 数组去掉所有维度后的类型,
文件格式验证:
0xCAFEBABY 魔数开头;
主次版本号当前虚拟机可处理;
常量类型;
索引执行类型;
utf8 编码数据类型,
元数据验证: 字节码描述信息语义分析:
是否有父类;
父类是否继承了 final 修饰的类;
非抽型类是否实现了父类或接口中需要实现的方法;
类中的字段方法的覆盖, 重载矛盾;
字节码验证: 通过语义流及控制流分析确定程序予以的合法性, 正确性, 方法体分析验证
符号引用验证: 虚拟机将符号引用转化为直接引用时候, 解析阶段, 对类自身以外信息进行匹配性验证
符号引用中通过字符描述的全限定名是否能找到对应的类;
指定类中是否存在符合方法字段的描述符, 及简单名称所描述的方法和字段;
符号引用中类, 字段, 方法的访问性
准备: 在方法区中为类变量分配内存及设置类变量初始值
初始值通常为数据类型的零值, final 修饰的值直接初始化为相应值
类变量为 static 修饰的变量, 区分于实例变量
解析: 虚拟机将常量池中的符号引用替换为直接引用过程
CONSTANT_Class_info,CONSTANT_Fieldref_info,CONSTANT_Methodref_info..
符号引用: 以一组符号来描述所引用的目标, 任何形式的字面量, 只要使用时能无歧义的定位到目标,, 与虚拟机内存实现无关, 无关引用目标是否加载
直接引用: 直接指向目标的指针, 偏移量或间接定位到目标的句柄, 和虚拟机实现的内存相关, 直接引用相关的目标对象必须已加载
初始化: 开始执行类定义中的 Java 程序代码执行类构造器 < cinit>()方法,
<cinit>():
编译器根据类文件中定义顺序自动收集类中的类变量的赋值动作和静态语句块儿的语句合并产生, 静态语句块儿只能访问到其前定义的变量
区别于类的构造方法, 不需要显示的调用父类构造器, 虚拟机保证子类的 < cinit>()执行之前父类的 < cinit>()已经执行完成
父类中的静态语句块儿执行于前
<cinit>()对于类或接口不是必须的, 如果没有变量赋值操作或静态语句块儿, 则不生成
接口的 < cinit>()不需要先执行父接口的 < cinit>(), 同样接口的实现类 < cinit>()也不需要
线程安全: 虚拟机保证多线程环境中 < cinit>()正确的加锁, 同步, 同一时间只能有一个线程访问初始化类的 < cinit>()
来源: http://www.phperz.com/article/18/0209/359178.html