深入学习理解JVM系列(五) -- 了解类文件结构

一、概述

  • 一次编写,到处运行(Write Once, Run Anywhere)
  • 与平台/语言无关:不同平台的Java虚拟机,都统一支持字节码(Byte Code)程序存储格式
  • Java虚拟机不与语言绑定,只和Class文件(二进制文件格式)关联
  • Class文件(强制性语法和结构约束)包括:Java虚拟机指令集、符号表、辅助信息

二、 Class类文件的结构

使用javap工具分析字节码:javap -verbose TestClass

  • 任何一个Class文件都对应着唯一的一个类或接口的定义信息
    但类或接口不一定需要定义在Class文件里(可以动态生成,送入类加载器中)
  • Class文件:一组以字节为基础单位的二进制流
  • 各个数据项严格按照顺序排列在文件之中,数据项需要占用多个字节空间时,按照高位在前(Big-Endian)的方式,分割成若干个字节存储
  • Class文件格式:类似于C语言结构体的伪结构,只有两种数据类型(无符号数、表)
    • 无符号数:u1/u2/u4/u8,代表1/2/4/8个字节的无符号数,描述数字、索引引用、数量值、字符串值
    • 表(_info结尾):多个无符号数或其他表作为数据项构成的复合数据类型,描述有层次关系的复合结构数据
  • Class文件可以当作一张表

1. 魔数与Class文件的版本

  • 魔数(Magic Number):开始4个字节(0xCAFEBABE),确定Class文件是否能被虚拟机接受
  • 版本号(4个字节:高版本JDK能向下兼容低版本的Class文件
    • 次版本号(Minor Version):一般固定为零
    • 主版本号(Major Version):JDK1.1:45,逐次加一,JDK8:52(0x0034)

2. 常量池(constant_pool)

  • Class文件占用空间最大的数据项之一,第一个表类型数据项
  • 入口:常量池容量计数值(constant_pool_count):u2,计数从1开始,0表示不引用任何一个常量池项目,0x0016(22-1项常量)
  • 存放:字面量(Literal)和符号引用(Symbolic References)
    • 字面量:常量(文本字符串、final常量值等)
    • 符号引用:
      • 被模块导出或者开放的包(Package)
      • 类和接口的全限定名(Fully Qualified Name)
      • 字段的名称和描述符(Descriptor)
      • 方法的名称和描述符
      • 方法句柄和方法类型(Method Handle、Method Type、Invoke Dynamic)
      • 动态调用点和动态常量(Dynamically- Computed Call Site、Dynamically- Computed Constant)
  • 当虚拟机做类加载时,将会从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址中
  • 常量池中每一项常量都是一个表,表结构的起始第一位:u1(标志位 tag)表示属于哪种常量类型

3. 访问标志(access_flags)

识别类或接口层次的访问信息:

  • 是类还是接口
  • 是否定义public类型
  • 是否定义abstract类型
  • 类是否声明为final
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值