• 注册
当前位置:1313e > java >正文

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

  我们都知道,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

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 162202241@qq.com 举报,一经查实,本站将立刻删除。

最新评论

欢迎您发表评论:

请登录之后再进行评论

登录