java的class类文件结构

利用五一小假期,看了一下java的类class文件结构,在此记录一下学习笔记。

字节码

程序的存储格式。语言无关。

跨平台。

class文件 — 概述

  • 包含了Java虚拟机指令集符号表,以及若干其他辅助信息。
  • class文件是一组以8位字节为基础单位的二进制流。大端方式存储。

class文件 — 结构

  1. 魔数、class文件的版本
    魔数:确定这个文件能被虚拟机接受。4个字节:0xCAFEBABE
    版本:紧接着魔数后面。4个字节。
              第5、6个字节标识次版本号。
              第7、8个字节标识主版本号。
     
  2. 常量池
    紧接着版本号,资源仓库。
    主要存放两大类常量:字面量(文本字符串、声明为final的常量值等)、符号引用。
    java代码javac编译,在虚拟机加载class文件时动态链接。
    当虚拟机运行时,需要从常量池获取对应的符号引用,再在类创建或运行时解析、翻译到具体的内存地址中。
    Java中如果定义超过64KB英文字符的变量或方法名,将无法解析。
     
  3. 访问标志
    用于识别一些类或接口层次的访问信息。
    比如public、final等。
     
  4. 类索引、父类索引、接口索引集合
    用这三项数据来确定这个类的继承关系。
    类索引:确定这个类的全限定名。
    父类索引:用于确定这个类的父类的全限定名。
    接口索引集合:用来描述这个类实现了哪些接口。
     
  5. 字段表集合
    用于描述接口或者类中声明的变量。
    包括的信息:字段的作用域、实例变量还是类变量、可变性、并发可见性、可否被序列化、字段数据类型、字段名称。
     
  6. 方法表集合
    对方法的描述,类似字段表集合。
    方法里的java代码,存储在“Code”属性里。
    Java中,要重载一个方法,要求必须拥有一个与原方法不同的特征签名。
     
  7. 属性表集合
    在class文件、字段表、方法表中,都可以携带自己的属性表集合,以用于描述某些场景专有的信息。

字节码指令简介

由一个字节长度的、代表着某种特定操作含义的数字、以及跟随其后的0至多个代表此操作所需参数构成。

  1. 字节码
    大部分的指令都没有支持byte、char、short,甚至完全没有boolean类型。编译器会在编译期或运行期将byte、short类型的数据带符号扩展为相应的int类型数据,将boolean和char类型数据零位扩展为相应的int类型数据。

    大多数对于boolean、byte、short、char类型数据的操作,实际上都是使用相应的int类型作为运算类型。
     
  2. 加载和存储指令
    用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。
     
  3. 运算指令
    用于对两个操作数栈上的值进行某种特定的运算,并把结果重新存入到操作栈顶。
    分为两种:对整型数据进行运算的指令、对浮点型数据运算的指令。
    舍入操作:向最接近数舍入模式。
     
  4. 类型转换指令
    将两种不同的数值类型相互转换。
    宽化类型转换、窄化类型转换。
     
  5. 对象创建与访问指令
    new、newarray、getfield、putfield、baload、bastore、arraylength、instanceof等等。
     
  6. 操作数栈管理指令
    pop、dup、swap等等。
     
  7. 控制转移指令
    在有条件或无条件地修改PC寄存器的值。
     
  8. 方法调用和返回指令
    invokevirtual、invokeinterface、invokespecial、invokestatic、invokedynamic等
     
  9. 异常处理指令
    显示抛出异常:athrow;
    虚拟机检测到异常字段抛出:如ArithmeticException。
     
  10. 同步指令
    使用管程来实现。

初步看完,有的地方还是有点难理解,而且感觉过段时间就会忘记。唯有日后不断思考、复习来加深印象。

扫描二维码关注公众号,回复: 96846 查看本文章

猜你喜欢

转载自my.oschina.net/xiaowangqiongyou/blog/1805295