字节码文件是什么

我们在命令后使用 java 命令,就能将java源文件(.java)编译成对应的字节码文件(.class)。字节码文件是一种八位字节的二进制流文件,各个数据项按照一定顺序从前到后紧密排列。因此,这样的安排会使得字节码文件非常紧凑,可以被jvm快速的加载到内存中,并且占用较少的内存空间。

java源文件在被编译器编译之后,每个类(或者接口)都单独占据一个字节码文件。类中所有信息都在字节码文件中有所描述,由于字节码文件非常灵活,它对类的描述能力甚至强于java源文件。

字节码文件中的信息是一项一项排列的,每一项都有各自固定的长度:有的占一个字节,有的占两个字节,有的占四个或八个字节。数据项不同的长度分别用u1, u2, u4, u8表示,对应数据项在字节码文件中占据1,2,4,8个字节。

字节码文件的结构

一个字节码文件由十部分构成:MagicNumber,Version,Constant_pool,Access_flag,This_class,Super_class,Interfaces,Fields,Methods和Attributes。可以用下面的表来展示他们的排列顺序和每一部分数据项的大小:

下面分别对每一项进行展开:

(1)magic:存在于字节码文件的开头四个字节,存放着字节码文件的魔数,他是一个固定值 0xCAFEBABE(英文就是java那个咖啡的图标)。如果是十六进制的CAFEBABE,那么这个文件符合字节码文件的标准;如果不是,则不能被jvm所识别。

(2)minor_version和major_version:紧跟着魔数的就是次版本号和主版本号。例如版本1.8.0,那么主版本号就是1.8,而此版本号对应是0。版本号与某一个整数之间有映射关系,因此只要将major_version的十六进制数转化为十进制,再查表找到映射关系,就可以知道java编译器的版本号。

(3)constant_pool:版本号后面为常量池,常量池是字节码文件中一个非常重要的部分。常量池存放了文字字符串,常量值,当前类的类名,字段名,方法名,各个字段和方法的描述符,对当前类的字段和方法的引用信息,当前类中对其他类的引用信息等等。几乎包含了类中所有信息的描述。

首先常量池开头两个字节描述了常量池中数据项的数目。常量池中的数据也是一项一项紧密排列的,各个数据项通过索引来访问。每一个数据项都有自己的数据类型,由开头的一个字节(标志值tag)决定,映射关系如下表所示:

每一种不同的数据类型,都对应不同的结构,例如CONSTANT_Methodref:

               CONSTANT_Methodref_info {u1 tag;    //u1表示占一个字节u2 class_index;    //u2表示占两个字节u2 name_and_type_index;    //u2表示占两个字节}

再比如CONSTANT_Utf8结构:

                    CONSTANT_Utf8_info {u1 tag;u2 length;u1 bytes[length];}

总而言之,每一个不同的数据类型都对应不同的组织结构。

(4)access_flag:保存了当前类的访问权限,包括了public,private,protected等等。

(5)this_class:保存了当前类的全局限定名在常量池中的索引。

(6)super_class:保存了当前类的父类全局限定名在常量池中的索引。

(7)interfaces:保存了当前类实现的接口列表,包括两个部分:interfaces_count和interfaces[interfaces_count]。前者表示当前类实现的接口数量,两个字节表示(因此理论上一个类最多实现65535个接口);后者表示包含interfaces_count个接口的全局限定名索引的数组。

(8)fields:保存了当前类中的成员列表,也是分为两部分:fields_count和fields[fields_count]。前者表示一个类中的成员个数,后者表示字段详细信息的列表,如下所示:

               field_info {u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];}

详细信息包括了访问权限,成员名在常量池中的索引,类型描述符在常量池的索引,一些其他的属性(比如volatile之类的,但count如果是0,这个字段也就不存在了)。

(9)methods:保存了当前类的方法列表,包含两部分的内容:methods_count和methods[methods_count]。前者是该类或者接口显示定义的方法的数量,后者包含方法信息的一个详细列表,每一个方法信息如下:

                    method_info {u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];}

这里的attribute比较复杂,涉及到操作数栈、局部变量表等等信息,不展开了。感兴趣的话可以看下结尾引用的那篇文章。

(10)attributes:包含了当前类的attributes列表,包含attributes_count和 attributes[attributes_count]。属性不仅仅可以出现在这个字段,如果出现在这个地方,则是对整个字节码文件所对应的类或者接口的描述;如果出现在fields或者methods中,则是对该字段或者该方法的额外信息的描述。

每一个attribute的结构如下:

          SourceFile_attribute {u2 attribute_name_index;u4 attribute_length;u2 sourcefile_index;}

最常见的一个属性就是attribute_name_index指向常量池中的SourceFile,而sourcefile_index指向常量池中的xxx.java(也就是这个字节码文件的源文件)。

总结

字节码文件中的十部分结构简单的分析如上所述,包含了让jvm识别的magic;java的版本号;常量池(各种成员名,方法名,类名,源文件名,方法描述符等等),这些常量信息被后面的field,method等等所引用;访问权限;类名和父类全限定名;实现的接口信息;类中成员和方法;类的额外属性。

如果想了解更具体的,可以参考一下深入理解JVM之Java字节码(.class)文件详解

最后放一个java代码,和编译后字节码文件的一部分信息(用javap反编译相当于对字节码文件进行解密):

源代码:

    public class Hello{private int test;public int test(){return test;}}

字节码文件:

javap反编译得到每一部分的值:

参考

  1. https://blog.csdn.net/weelyy/article/details/78969412
  2. 《深入理解java虚拟机》

字节码(.class)文件解读相关推荐

  1. 使用三种方式创建Class字节码类文件对象

    /*** 使用三种方式创建Class字节码类文件对象** @author silence*/ public class Demo1 {public static void main(String[] ...

  2. 进程创建java源代码_Java程序执行流程:1.创建Java源程序2.编译源程序3.运行class(字节码)文件...

    参考答案如下 2. 要准确理解复盘,程序1创程序程序哪几个关键词是不可缺少的? 执行字节影响电流对人体伤害程度的主要因素是()? 流程Sydney was established in: IE.建J件 ...

  3. 从一个class文件深入理解Java字节码结构

    前言 我们都知道,Java程序最终是转换成class文件执行在虚拟机上的,那么class文件是个怎样的结构,虚拟机又是如何处理去执行class文件里面的内容呢,这篇文章带你深入理解Java字节码中的结 ...

  4. 这一次,彻底弄懂 Java 字节码文件!

    作者 | 东升的思考 责编 | Elle 不啰嗦,直接从最最简单的一段Java源代码开启Java整体字节码分析之旅. Java 源码文件 package com.dskj.jvm.bytecode; ...

  5. java 字节码分析_Java 字节码实践 - 解读

    最近刚看完 深入理解 Java 虚拟机 一书中的第 6 章 (类文件结构),便迫不及待地自己写一个小的 Demo,来自己分析一把 Java 源文件经过编译之后成为字节码文件到底是个什么东西?先由一个简 ...

  6. Java反编译字节码文件

    如何查看 Java 的字节码文件? 在 Java 中,字节码文件.class实际上是二进制文件,并不能直接查看.要想查看,我们只能通过反编译对其进行解析,然后查看解析后的源码. 如何反编译字节码文件 ...

  7. python字节码大全

    ddis --- Python 字节码反汇编器 Source code: Lib/dis.py dis 模块通过反汇编支持CPython的 bytecode 分析.该模块作为输入的 CPython 字 ...

  8. idea如何反编译字节码指令_美团点评:Java字节码增强技术,线上问题诊断利器...

    作者简介:泽恩,美团到店住宿业务研发团队工程师.文章转载于公众号:美团技术团队 1. 字节码 1.1 什么是字节码? Java之所以可以"一次编译,到处运行",一是因为JVM针对各 ...

  9. Java 指令与字节码

    Java 指令与字节码 查看class文件 编写简单java代码 编译代码 查看class文件 Java字节码总的结构表 常量池 常量池容量计数器 字面量和符号引用 全限定名 简单名称 描述符 常量类 ...

  10. Python字节码介绍

    了解 Python 字节码是什么,Python 如何使用它来执行你的代码,以及知道它是如何帮到你的. 如果你曾经编写过 Python,或者只是使用过 Python,你或许经常会看到 Python 源代 ...

最新文章

  1. Redis、Kafka 和 Pulsar 消息队列对比,写得太好了!
  2. keil复制代码乱码_win7系统下Keil复制中文注释到记事本出现乱码的解决方法
  3. html和css入门 (三)
  4. python 开发gui浏览器_Python编程之gui程序实现简单文件浏览器代码
  5. 查看SQL SERVER数据库的连接数
  6. stm32f103电子钟心得体会_浅谈STM32_RTC闹钟
  7. 如何将nodejs项目程序部署到阿里云服务器上
  8. java对象--多态的好处
  9. 有关Silverlight浮动窗体组件的研究——Silverlight学习笔记(3)
  10. XMLHttpReq.onreadystatechange 传递参数
  11. 网上图书订阅系统的WBS图,和WBS字典
  12. Substance Painter 创建头发实验
  13. iOS 通过商品短链接跳转京东商品详情页
  14. minio 分片上传
  15. 贝尔曼福特_福特自行车之旅
  16. C - Wrap very long lines of input into two or more shorter lines
  17. 菜鸟站长之家带你了解什么是百度SEO快排技术
  18. n维椭球体积公式_2020中考物理知识汇总:公式大全
  19. 拟真机器人拯救者奖励_《X战警:黑队》万磁王大战哨兵机器人,他就是变种人的拯救者!...
  20. (一)操作系统的基本概念

热门文章

  1. blockly 工具箱
  2. 关于NLP中的文本预处理的完整教程
  3. 股票股利、现金股利、除权价格、股息红利税差别化
  4. 数据库(四)—— 数据库设计
  5. 认识对于java生活和工作的应该是怎么样的
  6. 2021全球50家最佳酒吧榜单揭晓3家在上海;星巴克中国推出全新鲜萃滴滤咖啡 | 食品饮料新品...
  7. 没读过大学也能去谷歌当工程师?未来硅谷想要怎样的人才?
  8. A、数据分析18种最常用的可视化分析模式之——对标分析
  9. dependencyManagament
  10. win10找不到组策略,解决方法