类文件结构和类加载机制

java 一次编译到处理运行

java虚拟机执行java是一件理所当然和天经地义的事情,jvm设计者通过JSR-292实现了其他语言理好地支持其他语言运行在jvm之上,

为了节省空间,类文件中没有任何分隔符,各个数据项都是一个挨着一个紧凑排列的,所以其中无论是顺序还是数量等都是严格规定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变

class类文件结构

任何一个class文件都对应着唯一一个类或接口的定义信息,反过来,类或接口并不一定都得定义在文件里,是因为类或接口也可以通过类加载器直接生成,这里所说的class文件不一定是以磁盘文件的形式所存在

class文件:一组以8位字节为基础单位的二进制流,紧凑地排列在c lass文件中,是间没有添加任何分隔符,利用伪结构:无符号表和表

   无符号:可以用来描述数字,索引引用,数量值或者按照UTF-8编码构成字符串值

  表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表的习惯“_info”结尾

  每个class文件头4个字节称为魔数,表示class文件的版本号,第5个和第6个字节次版本与,第7个和第8个表示主版本

 虚拟机可以向下兼容运行class文件,但不能运行高于其版本的class文件。

   随后是常量池,占两个字节

     由于常量池中的常量数量是不确定的,所以在常量池的入口需要有两个字节用来代表常量池容量计数值(常量池索引从1开始)。

   访问标志,占两个字节

   类索引,父类索引与接口索引集合,占3个字节

   字段表集合,占4个字节

 方法表集合,占6个字节

类加载:

   类型的加载,连接和初始化都在程序运行期间完成

  类加载的时机:

    加载--》验证--》准备--》解析--》初始化--》使用--》卸载

   加载--》验证--》准备--》初始化和卸载5个阶段的顺序是确定的,必须按部就班的地开始,便解析不一定

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

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的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则必须触发初始化。

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值