java编译与反编译

news2025/1/14 18:16:38

参考:

Idea 使用技巧记录_source code recreated from a .class file by intell_hresh的博客-CSDN博客

深入理解Java Class文件格式(一)_昨夜星辰_zhangjg的博客-CSDN博客

实践详解javap命令(反编译字节码)_天然玩家的博客-CSDN博客

 一、编译


1.1 编程语言

在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language)。

编程语言(Programming Language)分为低级语言(Low-level Language)和高级语言(High-level Language)。

机器语言(Machine Language)和汇编语言(Assembly Language)属于低级语言,直接用计算机指令编写程序。


而C、C++、Java、Python等属于高级语言,用语句(Statement)编写程序,语句是计算机指令的抽象表示。

1.2 编译

上面提到语言有两种,一种低级语言,一种高级语言。

简单的理解:低级语言是计算机认识的语言、高级语言是程序员认识的语言。
那么如何从高级语言转换成低级语言呢?这个过程其实就是编译。

将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序的过程就是编译。负责这一过程的处理的工具叫做编译器

现在我们知道了什么是编译,也知道了什么是编译器。不同的语言都有自己的编译器,Java 语言中负责编译的编译器是一个命令:javac

当我们写完一个 HelloWorld.java 文件后,我们可以使用 javac HelloWorld.java
命令来生成 HelloWorld.class 文件,这个 class 类型的文件是JVM可以识别的文件。通常我们认为这个过程叫做 Java 语言的编译。其实,class 文件仍然不是机器能够识别的语言,因为机器只能识别机器语言,还需要 JVM 再将这种 class文件类型字节码转换成机器可以识别的机器语言。

javac是收录于JDK中的Java语言编译器。该工具可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于Java虚拟机的字节码。

我们都知道Java有自己的语言规范,JVM也有自己的解析规则,Java程序能够运行在虚拟机上,得益于javac编译器,将Java语言编译成字节码,javac属于静态编译,因为它不能直接把程序源码编译成机器可以识别的机器码,javac将程序整个完全编译成字节码后,才能交由虚拟机解释执行,这个过程需要耗费的时间(对比于其他可一边编译一边执行的语言)和空间(整个完全编译完成)都比较大。

1.2.1 编译举例

编写hello world程序,HelloWorld.java

public class HelloWorld {
    public static void main(String[] args) {
        for (int i =0;i<=5;i++){
            System.out.println("hello world");
        }
    }
}

实现编译的方式,有两种。

方式一

 javac HelloWorld.java 

在当前路径下,生成HelloWorld.class 文件。

方式二:

在idea中,直接运行程序,会自动在target文件下,生成HelloWorld.class文件。

1.2.2 查看字节码class文件

1、在idea中,查看

在idea中,直接查看HelloWorld.class,idea自动对该文件进行了反编译。

观察发现,源文件,与编译后,再反编译的文件有点小小的区别。

我们对于优化二字定义稍微宽松一些,因为Javac编译器对代码运行效率几乎没有任何优化措施,虚拟机设计团队将对性能的优化集中到了后端的JIT中,这样可以让那些不是由javac产生的class文件(Groovy JRuby等语言的class文件)也同样能享受到编译器优化带来的好处。但是Javac做了许多针对编码的优化措施来改善程序员的编码风格和提高编码效率。相当多新生的Java语法特性,都是靠编译器的语法糖来实现,而不是依赖虚拟机的底层改进来支持。Java中JIT在运行期的优化过程对于程序运行更加重要,而前端编译器在编译期的优化过程对于程序编码来说关系更加密切。

javac在编译Java程序时会进行一些优化。这些优化旨在提高程序的性能和执行效率。
在编译过程中,javac会对代码进行静态分析和优化。它会检查代码中的错误并进行纠正,同时还会尝试改善生成的字节码的质量。例如,javac可以对常量进行折叠(constant folding),消除无用的代码(dead code elimination),将循环展开(loop unrolling),减少函数调用开销等等。这些优化可以减少代码的执行时间和内存消耗。
当你提到源文件与编译再反编译之后的文件之间有小小的区别时,这可能是由于编译器对代码进行了优化所致。优化可能导致生成的字节码与原始源代码略有不同,但仍保持相同的逻辑功能。这是正常的行为,因为优化的目标是提高代码的执行效率,而不是保持与原始源代码的完全一致性。
需要注意的是,不同的编译器可能会应用不同的优化策略和技术,因此在不同的编译环境下,反编译后的代码可能会有细微差异。


1.2 使用txt文件查看

我们可以使用txt程序,来打开HelloWorld.class文件,查看字节码。

cafe babe 0000 0034 001e 0a00 0600 1009
0011 0012 0800 130a 0014 0015 0700 1607
0017 0100 063c 696e 6974 3e01 0003 2829
5601 0004 436f 6465 0100 0f4c 696e 654e
756d 6265 7254 6162 6c65 0100 046d 6169
6e01 0016 285b 4c6a 6176 612f 6c61 6e67
2f53 7472 696e 673b 2956 0100 0d53 7461
636b 4d61 7054 6162 6c65 0100 0a53 6f75
7263 6546 696c 6501 000f 4865 6c6c 6f57
6f72 6c64 2e6a 6176 610c 0007 0008 0700
180c 0019 001a 0100 0b68 656c 6c6f 2077
6f72 6c64 0700 1b0c 001c 001d 0100 1179
6f75 6875 612f 4865 6c6c 6f57 6f72 6c64
0100 106a 6176 612f 6c61 6e67 2f4f 626a
6563 7401 0010 6a61 7661 2f6c 616e 672f
5379 7374 656d 0100 036f 7574 0100 154c
6a61 7661 2f69 6f2f 5072 696e 7453 7472
6561 6d3b 0100 136a 6176 612f 696f 2f50
7269 6e74 5374 7265 616d 0100 0770 7269
6e74 6c6e 0100 1528 4c6a 6176 612f 6c61
6e67 2f53 7472 696e 673b 2956 0021 0005
0006 0000 0000 0002 0001 0007 0008 0001
0009 0000 001d 0001 0001 0000 0005 2ab7
0001 b100 0000 0100 0a00 0000 0600 0100
0000 0300 0900 0b00 0c00 0100 0900 0000
4900 0200 0200 0000 1603 3c1b 08a3 0011
b200 0212 03b6 0004 8401 01a7 fff0 b100
0000 0200 0a00 0000 1200 0400 0000 0500
0700 0600 0f00 0500 1500 0800 0d00 0000
0900 02fc 0002 01fa 0012 0001 000e 0000
0002 000f 

class文件是一种8位字节的二进制流文件(文件通过二进制存储,以8个字节为一组,所以以16进制展示), 各个数据项按顺序紧密的从前向后排列, 相邻的项之间没有间隙, 这样可以使得class文件非常紧凑, 体积轻巧, 可以被JVM快速的加载至内存, 并且占据较少的内存空间。 我们的Java源文件, 在被编译之后, 每个类(或者接口)都单独占据一个class文件, 并且类中的所有信息都会在class文件中有相应的描述, 由于class文件很灵活, 它甚至比Java源文件有着更强的描述能力。

class文件中的信息是一项一项排列的, 每项数据都有它的固定长度, 有的占一个字节, 有的占两个字节, 还有的占四个字节或8个字节, 数据项的不同长度分别用u1, u2, u4, u8表示, 分别表示一种数据项在class文件中占据一个字节, 两个字节, 4个字节和8个字节。 可以把u1, u2, u3, u4看做class文件数据项的“类型” 。

1.3 反编译

java提供了可以解析class文件称为字节码文件的工具,把这个class文件,翻译成字节码文件,告诉虚拟机你要去做什么操作。

javap -v

举例:

javap -v HelloWorld.class

源码:

public class HelloWorld {
    public static void main(String[] args) {
        String s1 = "hello" + "world";
        String s2 = "hello".concat(("world"));
        System.out.println(s1 == s2);
    }
}

编译:

javac HelloWorld.java  

反编译

javap -v HelloWorld.class

 类文件大小:size 639 bytes

类文件MD5:MD5 checksum 402978bba57b05316db982dabcf3e7f3

类文件源文件名称: Compiled from "HelloWorld.java"

常量池:Constant pool:


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/684623.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【运筹优化】元启发式算法详解:迭代局部搜索算法(Iterated Local Search,ILS)+ 案例讲解代码实现

文章目录 一、介绍二、迭代局部搜索2.1 总体框架2.2 随机重启2.3 在 S* 中搜索2.4 ILS 三、获得高性能3.1 初始解决方案3.2 Perturbation3.2.1 扰动强度3.2.2 自适应扰动3.2.3 更复杂的扰动方案3.2.4 Speed 3.3 接受准则3.4 Local Search3.5 ILS 的全局优化 四、ILS 的精选应用…

Windows PE怎么修复系统?使用轻松备份解决!

​什么是Windows PE? Windows预先安装环境&#xff08;英语&#xff1a;Microsoft Windows Preinstallation Environment&#xff09;&#xff0c;简称Windows PE或WinPE&#xff0c;是Microsoft Windows的轻量版本&#xff0c;主要提供个人电脑开发商&#xff08;主要为OEM厂…

electron+vue3全家桶+vite项目搭建【20】窗口事件广播,通用事件封装

引入 electron中的渲染进程与主进程之间的数据交互需要利用ipc通信&#xff0c;互相订阅/通知来实现&#xff0c;我们不妨封装一个通用事件广播&#xff0c;利用自定义的事件名称来让主进程遍历窗口挨个推送对应内容&#xff0c;来实现事件的广播。 demo项目地址 实现思路 …

【计算机视觉】MaskFormer:将语义分割和实例分割作为同一任务进行训练

文章目录 一、导读二、逐像素分类和掩码分类的区别2.1 逐像素分类2.2 掩码分类2.3 区别 三、DETR四、MaskFormer五、MaskFormer用于语义和实例分割六、总结 一、导读 目标检测和实例分割是计算机视觉的基本任务&#xff0c;在从自动驾驶到医学成像的无数应用中发挥着关键作用。…

模拟电路系列分享-运放的关键参数5

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 例如&#xff1a; 实际运放与理想运放具有很多差别。理想运放就像一个十全十美的人&#xff0c;他学习100 分&#xff0c;寿命无限长&#xff0c;长得没挑剔&#xff0c;而实…

【c++11】移动构造的性质 和 与拷贝构造的比较(详解)

文章目录 定义性质移动构造的定义实例代码分析移动构造 与 拷贝构造的比较移动赋值 和 拷贝赋值 应用场景 定义 移动构造&#xff08;Move Constructor&#xff09;是一种特殊的构造函数&#xff0c;它通过接收一个右值引用参数来创建新对象&#xff0c;并从传入的对象中“移动…

操作系统——Windows 线程的互斥与同步

一、实验题目 Windows 线程的互斥与同步 二、实验目的 (1) 回顾操作系统进程、线程的有关概念&#xff0c;加深对 Windows 线程的理解。 (2) 了解互斥体对象&#xff0c;利用互斥与同步操作编写生产者-消费者问题的并发程序&#xff0c;加深对 P (即 semWait)、V(即 semSig…

[Spec] WiFi P2P Discovery

学习资料&#xff1a;Android Miracast 投屏 目录 学习资料&#xff1a;Android Miracast 投屏 P2P discovery Introduction Device Discovery procedures Listen State Search State Scan Phase Find Phase 总结 P2P discovery Introduction P2P发现使P2P设备能够快速…

WiSA Technologies开始接受WiSA E多声道音频开发套件的预订

美国俄勒冈州比弗顿市 — 2023年6月13日 — 为智能设备和下一代家庭娱乐系统提供沉浸式无线声效技术的领先供应商WiSA Technologies股份有限公司&#xff08;NASDAQ股票代码&#xff1a;WISA&#xff09;宣布&#xff1a;该公司现在正在接受其WiSA E开发套件的预订。WiSA E使用…

论文不详细解读(一)——MoCo系列

1. MoCo v1 论文名称&#xff1a; Momentum Contrast for Unsupervised Visual Representation Learning 开源地址&#xff1a;https://github.com/facebookresearch/moco 大佬详细解读&#xff1a;https://zhuanlan.zhihu.com/p/382763210 motivation 原始的端到端自监督方…

听说软件测试岗位基本都是女孩子在做?

“听我一朋友说&#xff0c;测试岗位基本都是女孩子做。” 不知道是不是以前“软件测试岗”给人印象是“不需要太多技术含量”的错觉&#xff0c;从而大部分外行认为从业软件测试的人员中女生应占了大多数。比如有人就觉得&#xff1a;软件测试主要是细心活&#xff0c;所以女生…

Python多任务执行方式

一、多任务的执行方式 并发&#xff1a;在一段时间内交替去执行任务&#xff08;单核CPU&#xff09;并行&#xff1a;CPU核数大于任务数 二、进程&#xff08;实现多任务&#xff09;——操作系统调度 进程是操作系统进行资源分配的基本单元一个程序至少有一个进程&#xf…

极致呈现系列之:EchartsK线图的数据量化

目录 什么是K线图K线图的特性及应用场景K线图的特性K线图的应用场景 Echarts中K线图的常用属性Vue3中创建K线图 什么是K线图 K线图是一种用于展示金融市场中股票、期货、外汇等交易品种价格走势的图表形式。它由一根根的垂直线条和水平线组成&#xff0c;能够直观地显示出一段…

OJ #378 字符串括号匹配2

题目描述 ​ 给出一个字符串&#xff0c;判断其中的左右括号是否匹配。 ​ 注&#xff1a;需同时判断左右圆括号 ( 和 ) &#xff0c;左右中括号 [和]&#xff0c;左右大括号 {和}。 ​ 不需要考虑括号之间的优先级的问题&#xff0c;也就是说&#xff0c;小括号包含大括号&…

NodeJS应届毕业生财务管理系统-计算机毕设 附源码82886

基于VueNodeJS应届毕业生财务管理系统 摘 要 随着互联网大趋势的到来&#xff0c;社会的方方面面&#xff0c;各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去&#xff0c;而其中最好的方式就是建立网络管理系统&#xff0c;并对其进行信息管理。由于现在…

合宙Air724UG Cat.1模块硬件设计指南--看门狗

概述 Air724UG 内部已经自带了看门狗&#xff0c;4秒进行一次喂狗&#xff0c;如果主芯片异常死机&#xff0c;自带的看门狗15秒左右会硬件复位主芯片。 另外主芯片死机情况下&#xff0c;reset键也可以硬重启。 通常情况下不需要外加硬件看门狗&#xff0c;如果对系统稳定性有…

FreeRTOS和uC/OS:选择入手哪个RTOS更合适?

FreeRTOS和uC/OS是两个流行的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;用于嵌入式系统开发。它们有一些区别&#xff0c;但选择哪个先入手取决于你的需求和项目要求。 复杂度&#xff1a;FreeRTOS是一个相对较简单的RTOS&#xff0c;它专注于提供基本的实时调度和…

西门子Mendix 入门 3

导航页面&#xff1a;用于在应用程序中添加或修改其他页面 创建查看查看和添加公司不同部门的页面 打开导航页面&#xff0c;添加新项目 选择TaskTracke新建一个名为Department_Overview的页面&#xff0c;并选择List作为模板 创建成功 现在转到 Department_Overview页面 链接数…

揭秘2023年项目管理软件排行榜实力榜

在现代的商业世界中&#xff0c;项目管理是必不可少的一个组成部分。为了成功地管理一个项目&#xff0c;项目经理需要实施一种系统化的方法来确保项目在时间和预算的约束下成功。这就需要使用专业的项目管理软件。因此&#xff0c;项目管理软件在商业领域中扮演着至关重要的角…

管理类联考——逻辑——知识篇——分析推理——一、排序——haimian

排序 题型特征 排序题通常是依据大小、时间、名次和前后等条件将几个元素有序地排在若干连续排列的位置上。解题时要找出一个对整个排列起决定作用的条件&#xff0c;然后涉及先后位置的条件尽可能结合起来进行解题。 思维导图 思路点拨 注意选项的模式&#xff0c;如果已经…