深入理解java虚拟机之类文件结构以及加载

本文介绍了Java作为一种平台无关的语言的特点,以及Java虚拟机如何加载class文件的过程。文章详细阐述了类文件的结构,并解释了类加载、验证、初始化等生命周期阶段。

  我们都知道,java是一种平台无关的语言。java代码通过java编译器(如javac等),将.java文件编译成字节码,也就是.class文件。字节码是运行在jvm虚拟机之上的。而不同的平台则 有不同的虚拟机映射规则。因此,我们从虚拟机上面一层来看,java是平台无关的。write once ,写的java程序,只要在装了jre的电脑,或者任何设备中,都可以运行,也就是run anywhere.

  下面主要介绍一下从深入理解Java虚拟机中学习到的类文件结构,也就是class文件规范。

class文件,按照以下的数据项,不论是顺序还是数量甚至数据存储的字节序(大端法)都是严格规定的,哪个字节代表什么含义长度先后顺序都不能改变。u1 u2 u4 u8表示1 2 48个字节的无符号数,可以用来描述数字 索引引用,数量值或者按照UTF-8构成的字符串值。

类型名称数量
u4magic1
u2minor_version1
u2major_version1
u2constant_pool_count1
cp_infoconstant_poolconstant_pool_count - 1
u2access_flags1
u2this_class1
u2super_class1
u2interfaces_count1
u2interfacesinterfaces_count
u2fields_count1
field_infofieldsfields_count
u2methods_count1
method_infomethodsmethods_count
u2attribute_count1
attribute_infoattributesattributes_count

 

针对上述结构,对于每个info,又有很多内容。详细参见深入java虚拟机把。。。。

 

接下来谈一下,Java虚拟机如何夹杂class文件,以及class文件被加载到虚拟机后又发生了什么?

java虚拟机的类加载机制:虚拟机将描述类的数据从class文件中加载到内存,然后对数据进行校验,转换解析,初始化,最终形成可以被虚拟机直接利用的java类型的过程。

java加载链接和初始化,都是在程序运行时完成的。

类的生命周期:加载--验证--准备--解析--初始化--使用--卸载。

在什么情况下会触发初始化?

1.new(创建实例指令) getstatic putstatic invokestatic(访问类字段,或者成为类变量):使用new实例化对象时,读取或者设置一个静态字段(被final修饰已在编译期把结果放入常量池的静态字段除外)以及调用静态方法时

2.使用java.lang.reflect包对类进行反射调用。如果类没有初始化,首先触发初始化。

3.初始化一个类时,如果父类还没有被初始化,那么先要触发其父类的初始化。

4.虚拟机启动时,用户需要指定一个需要执行的主类(就是main()的那个类) 虚拟机会首先初始化这个主类。

5.jdk1.7以上,动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的结果REF_getstatic,REF_putstatic,REF_invokestatic的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则必须触发初始化。

虚拟机规范中指明:有且只有 以上行为才会初始化,称为主动引用。除此之外的任何引用类的方法,都不会触发初始化,称之为被动引用。

其实根据以上五条规则,就可以知道类的加载顺序了。

 

转载于:https://www.cnblogs.com/CongLollipop/p/6666410.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值