详解JAVA字节码
目录
1.概述
2.字节码文件构成
2.1.魔数
2.2.版本号
2.3.常量池
2.4.访问标志
2.5.索引
2.6.字段表
2.7.方法表
3.字节码指令
3.1.概述
3.2.指令分类
3.2.1.加载存储指令
3.2.2.运算指令
3.2.3.其他指令
3.3.完整指令工作流程
4.字节码保护
1.概述
以往的编程语言是直接编译为计算机可识别并直接执行的机器码,但不同平台(机器)的指令集不同,编译出来的机器码不同,一个平台编译出来的机器码在另一个平台上可能无法正常运行。JAVA为了实现“write once run anywhere”的效果,先将JAVA代码编译为平台无关的.class文件(字节码文件),不论什么平台编译出来的字节码都是一样的,然后用适配不同平台的JVM来加载字节码文件,将字节码文件翻译给对应平台来执行。
字节码文件是个二进制文件,由JVM定义字节码文件的规范,任何满足这种规范的class文件都会被JVM加载运行。字节码规范规定字节码应该具有以下基本结构:
2.字节码文件构成
2.1.魔数
字节码的前4个字节是魔数,所有字节码文件的魔数是固定的,4个byte合起来是cafebabe,用来标识该文件是JAVA的class文件。
2.2.版本号
字节码中记录编译使用的JDK版本,字节码的第5、6位表示次版本号,第7、8位表示主版本号:
查表可以得,示例中的版本号为JDK12。
2.3.常量池
常量池存放两大类常量:
- 字面量,如文本字符串、fnal的常量值等
- 符号引用,类和接口的全限定名、字段的名称和描述符、方法的名称和描述符
字节码中存放有常量池,使用java -verbose命令可以反编译得到常量池信息。
2.4.访问标志
常量池结束后的两个字节,描述了该Class是类还是接口,以及是否被public、abstart、final等修饰符修饰。
2.5.索引
字节码文件中的索引分为三类:
- 类索引
- 父类索引
- 接口索引集合
类索引:
访问标志后的两个字节,描述的是当前类的全限定名,这两个字节保存的值为常量池中的索引值,根据索引值就能在常量池中找到这个类的全限定名
父类索引:
当前类名后的两个字节描述父类的全限定名,同上,保存的也是常量池中的索引值。
接口索引集合:
父类名称后为两字节的接口计数器,描述了该类或父类实现的接口数量。紧接着的n个字节是所有接口名称的字符串常量的索引值。
2.6.字段表
用来记录成员变量,分为两部分:
- 计数器,记录成员变量的个数。
- 数据区,记录变量的具体内容。
2.7.方法表
记录方法,分为两部分:
- 计数器,记录方法的个数
- 数据区,记录方法的具体内容
属性列表中记录了方法的具体内容:
- Code,源代码对应的]VM指令操作码
- LineNumberTable,行号表,将Code区的操作码和源代码中的行号对应
3.字节码指令
3.1.概述
字节码指令在栈里面的每个栈帧中操作局部变量表进行对操作数栈的压栈出栈,从而完成方法中编写的一系列内容,变量表是“菜篮”;操作数栈是“砧板”。
3.2.指令分类
3.2.1.加载存储指令
用于变量对于操作数栈的压栈、出栈。
- 用于将数据在栈帧中的局部变量表和操作数栈之间来回传输
- 将一个局部变量加载到操作栈: iload、lload、fload、dload、aload等
- 将一个数值从操作数栈存储到局部变量表: istore、Istore、fstore、dstore、astore等
- 将一个常量加载到操作数栈: bipush、sipush、ldc、ldc_w、ldc2 w、aconst null、iconst m1等
3.2.2.运算指令
用于进行运算的指令。
- iadd、isub、imul、idiv等类型转换指令
- i2b、i2l、i2s等对象/数组创建与访问指令
- new、newarray、getfield等操作数栈管理指令
- pop、dup等
3.2.3.其他指令
- lfeq、goto等方法调用和返回指令
- invokevirtual、ireturn等异常处理指令
- athrow同步控制指令
- monitorenter、monitorexit
3.3.完整指令工作流程
以下面代码为例展示一个完整的指令工作流程:
public class Sum {private int base = 10;public long add(int toAdd){this .base += toAdd;return this.base;}
}
反编译查看源码:
整体步骤如下:
- aload 0 将索引为0的局部变量压栈
- dup 复制栈顶值并压栈
- getfeld 取出栈顶对象引用,获取其成员变量并压栈
- iload_1 将索引为1 int型局部变量压栈
- iacd 取出栈顶两个int型值相加,结来压栈
- puteld 将栈顶两个元素取出 (值和对象引用) ,将值赋给该对象宇段
- i2l 将栈顶int型值取出转为long型压栈lreturn 将栈顶long型元素取出返回
4.字节码保护
防止字节码文件被反编译为.java文件,一般有两种手段:
- 字节码保护
- 字节码混淆
字节码保护:
对字节码进行加密使其不再遵循JVM的规范,JVM加载之前先解密。
字节码混淆:
被混淆代码依然遵循JVM制定的规范,变量命名和程序流程上进行等效替换,使得程序的可读性变差,使得代码难以被理解和重用,达到保护代码的效果。
常用的字节码混淆器:ProGuard
下载地址:https://www.guardsquare.com/en/products/proguard
相关文章:

详解JAVA字节码
目录 1.概述 2.字节码文件构成 2.1.魔数 2.2.版本号 2.3.常量池 2.4.访问标志 2.5.索引 2.6.字段表 2.7.方法表 3.字节码指令 3.1.概述 3.2.指令分类 3.2.1.加载存储指令 3.2.2.运算指令 3.2.3.其他指令 3.3.完整指令工作流程 4.字节码保护 1.概述 以往的编程…...

前端利用emailjs发送邮件
最近有一个需求,前端发送一个form表单到一个邮箱,找了一圈发现emailjs还不错就使用他了。首先emailjs官网注册一个账号注册完之后创建一个邮件服务(我这里使用的是谷歌邮箱)链接谷歌邮箱账户 然后创建服务接下来就要创建一个邮件的…...

16 Nacos服务端服务注册源码分析
Nacos服务端服务注册源码分析 服务端调用接口 我们已经知道客户端在注册服务的时候实际上是调用的NamingService.registerInstance这个方法来完成实例的注册,而且在最后我们也告诉了大家实际上从本质上讲服务注册就是调用的对应接口nacos/v1/ns/instanceÿ…...
Spring Boot2中如何优雅地个性化定制Jackson
概述 本文的编写初衷,是想了解一下Spring Boot2中,具体是怎么序列化和反序列化JSR 310日期时间体系的,Spring MVC应用场景有如下两个: 使用RequestBody来获取JSON参数并封装成实体对象;使用ResponseBody来把返回给前…...
2023年全国最新食品安全管理员精选真题及答案11
百分百题库提供食品安全管理员考试试题、食品安全员考试预测题、食品安全管理员考试真题、食品安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 101.婴幼儿配方乳粉的产品配方应当经()部门注册。…...

【脚本】用于得到某个文件/文件夹所有文件的存储大小(MB单位)
知识点 来自在线转换换算网页:在线文件大小(bit,bytes,KB,MB,GB,TB)转换换算 电脑中存储常用的单位: 1Byte(Byte 字节) 8Bit 1KB (Kilobyte 千字节) 1024Byte 1MB (Megabyte,兆字节,简称“兆”) 1024KB 1GB (Gigabyte&am…...

19- CNN进行Fashion-MNIST分类 (tensorflow系列) (项目十九)
项目要点 Fashion-MNIST总共有十个类别的图像。代码运行位置 CPU: cputf.config.set_visible_devices(tf.config.list_physical_devices("CPU"))fashion_mnist keras.datasets.fashion_mnist # fashion_mnist 数据导入训练数据和测试数据拆分: x_valid, x_train…...

【正点原子FPGA连载】第二十二章IP封装与接口定义实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南
1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第二十二章IP封装…...

【ElasticSearch8.X】学习笔记(二)
【ElasticSearch8.X】学习笔记四、基础操作4.1、索引操作4.1.1、创建索引4.1.2、查询指定索引4.1.3、查询所有索引4.1.4、 删除索引4.2、文档操作4.2.1、创建文档4.2.2、查询文档4.2.3、修改文档4.2.4、删除文档4.2.5、查询所有文档4.3、数据搜索4.3.1、匹配查询文档4.3.2、匹配…...

Ubuntu22.04安装、配置、美化、软件安装、配置开发环境
Ubuntu22.04安装、配置、美化、软件安装、配置开发环境 一、Ubuntu、Windows11(10)双系统安装 因为ubuntu的安装网上的教程特别多了,所以这里不做赘述,推荐使用小破站这个up主的教程:Windows 和 Ubuntu 双系统从安装到…...

企业电子招投标采购系统之系统的首页设计
功能模块: 待办消息,招标公告,中标公告,信息发布 描述: 全过程数字化采购管理,打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力,为…...

Python爬虫-阿里翻译_csrf
前言 本文是该专栏的第37篇,后面会持续分享python爬虫干货知识,记得关注。 笔者在前面有介绍过百度翻译的案例,感兴趣的同学,可往前翻阅查看(JS逆向-百度翻译sign)。而本文,笔者要介绍的是阿里翻译,相对于百度翻译的参数被逆向需要花点时间,阿里相对于易上手。 下面…...

C语言实现三子棋【详解+全部源码】
大家好,我是你们熟悉的恒川 今天我们用C语言来实现三子棋 实现的过程很难,但我们一定要不放弃 三子棋1. 配置运行环境2. 三子棋游戏的初步实现2.1 建立三子棋分布模块2.2 创建一个名为board的二维数组并进行初始化2.3 搭建棋盘3. 接下来该讨论的事情3.1 …...

双指针法将时间复杂度从 O(n^2) 优化到 O(n)
[1] 什么是双指针法 双指针法(Two Pointers)是一种常见的算法技巧,常用于数组和链表等数据结构中。 双指针法的基本思想是维护两个指针,分别指向不同的位置,通过它们的移动来解决问题。在某些情况下,使用双…...
【SpringBoot系列】 Spring中自定义Session管理,Spring Session源码解析
系列文章:Spring Boot学习大纲,可以留言自己想了解的技术点 目录 系列文章:Spring Boot学习大纲,可以留言自己想了解的技术...

【上位机入门常见问题】SQLServer2019 安装指导
SQLServer2019 安装指导 这里要说一下SQLServer的版本问题,首先说纵向的高低版本,如果大家跟我学习,我教给大家的是T-SQL编程的方法,而不是直接操作菜单的方法,所以,我们学习中只要使用SQLServer2012或以上…...

RabbitMQ第一讲
目录 一、RabbitMQ-01 1.1 MQ概述 1.2 MQ的优势和劣势 1.2.1 优势 1.2.2 劣势 1.2.3 MQ应用场景 1.2.4 常用的MQ产品 1.3 RabbitMQ的基本介绍 1.3.1 AMQP介绍 1.3.2 RabbitMQ基础架构 1.3.3 RabbitMQ的6种工作模式 编辑 1.4 AMQP和JMS 1.4.1 AMQP 1.4.2 JMS …...

华为机试题:HJ100 等差数列(python)
文章目录(1)题目描述(2)Python3实现(3)知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…...

数据推荐 | 人体行为识别数据集
人体行为识别任务旨在通过对人体姿态进行分析,识别出人体的具体动作,为人体行为预测、突发事件处理、智能健身、智能看护等领域提供技术支持。 图片 图片 人体行为识别数据标注方式 人体行为数据通用的标注方式包括人体关键点标注和动作标签标注&#…...
667真题分析 | 2023年667真题简要分析和答题思路参考
2023年667真题简要分析和答题思路参考 文章目录 2023年667真题简要分析和答题思路参考前言1. 名词解释2. 简答题3. 分析题3.1 答题框架(套路)3.2 答题框架实战3.2.1 图书情报档案事业如何在文化自信、文化强国中发挥自己的地位和作用3.2.2 高校图书馆如何发挥空间资源的功能和…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...
boost::filesystem::path文件路径使用详解和示例
boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类,封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解,包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...
Android屏幕刷新率与FPS(Frames Per Second) 120hz
Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数,单位是赫兹(Hz)。 60Hz 屏幕:每秒刷新 60 次,每次刷新间隔约 16.67ms 90Hz 屏幕:每秒刷新 90 次,…...

Axure零基础跟我学:展开与收回
亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...