第六章 类文件结构(读深入理解jvm虚拟机,随记)

6.2  无关性的基石

   标题为什么是无关性基石呢。时至今日,商业机构和开源机构已经在java语言之外发展出一大批在java虚拟机上运行的语言。如Clojure,Groovy,Scala等。

   java虚拟机不和包括java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式有所关联。  java程序(*.java)------>javac编译器------>字节码文件----->java虚拟机。

6.3  Class类文件的结构

   如果想比较深入的了解虚拟机,那么这部分是不能不接触的。

   注意⚠️:任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成)。

  Class文件是一组以8位字节为基础单位的二进制流,各个数据项严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符。

  Class文件采用一种类似于C语言结构体的伪结构来存储数据。其只有两种数据类型:无符号数和表。

  无符号数:属于基本数据类型。以u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数。无符号数可以用来描述:数字,索引引用,数量值或者按UTF-8编码构成字符串值。

  表是由多个无符号数或者其他表构成的复合数据类型。都以“_info”结尾。 整个Class文件本质上就是一张表。

  

    以上是Class文件的基本组成概述。后续继续详细介绍哪几个字节分别代表什么。

 

(1)魔数,class文件的版本(magic,minor_version,major_version)

        每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否是一个可以被虚拟机接受的文件。

        第5和第6字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)。jdk1.1是(45~45.3),1.2是(45~46.3)以此类推,每次加一。

(2)常量池(constant_pool_count,constant_pool是表类型)

         在主次版本号之后的是常量池入口,常量池可以理解为Class文件之中的资源仓库。

         常量池主要存放两大类常量:字面量(Literal)和符号引用。

 字面量比较接近于java语言层面的常量概念,如文本字符串,声明为final的常量值等。

(3)访问标志位(access_flags)

         常量池之后的两个字节代表 访问标志位(access_flags)。这个标志用于识别一些类或者接口层次的访问信息。包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final等。

(4)类索引,父类索引与接口索引集合

         类索引(this_class)和父类索引(super_class)都是一个u2类型的数据,而接口索引集合(interfaces)是一组u2类型数据的集合,Class文件中由这三项数据来确定这个类的继承关系。

(5)字段表集合

         字段表(field_info)用于描述接口或者类中声明的变量。字段(field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。

字段包括的信息有:字段的作用域(public,private,protected修饰符),是实例变量还是类变量(static修饰符),可变性(final),并发可见性(volatile修饰符,是否强制从主内存读写),可否被序列化(transient修饰符),字段数据类型,字段名称。

(6)方法表集合

(7)属性表集合

         在Class文件,字段表,方法表都可以携带自己的属性表集合,以用于描述某些场景的专有信息。

6.4 字节码指令简介

  (1)字节码与数据类型

         在java虚拟机的指令集中,大多数的指令都包含了其操作所对应的数据类型信息。

  (2)加载和存储指令

         加载和存储指令用于将数据在栈帧中的 局部变量表 和 操作数栈 之间来回传输。

  (3)运算指令

  (4)类型转换指令

  (5)对象创建与访问指令

  (6)操作数栈管理指令

  (7)控制转移指令

  (8)方法调用和返回指令

  (9)异常处理指令

  (10)同步指令

posted @ 2016-02-26 23:37  张-晓  阅读(241)  评论(0编辑  收藏  举报