当前位置: 首页 > 科技观察

Java编译反编译呢

时间:2023-03-13 02:03:31 科技观察

前言好久没更新文章了。之前面试了一个月,然后写了一篇文章。有朋友找我交流问题,一直没时间写技术文章。我估计以后更新文章的频率不会那么高,但我还是会定期分享。我的目的是希望大家能从我的每篇文章中有所收获。基本概念我们可以使用javac命令将一个Java程序的源代码编译成一段Java代码,也就是我们常说的class文件,就是我们平时理解的编译。但是,字节码不是机器语言。要让机器执行,就需要将字节码翻译成机器指令。这个过程是通过解释器实现的,叫做解释执行注意:不要把编译和解释执行混为一谈,后文提到的后端编译过程是JVM为了提高效率所做的优化。在不同的虚拟机实现中,执行引擎在执行字节码时,通常有两种选择:解释执行(通过解释器执行)和编译执行(通过即时编译器执行本地代码),或者两者兼而有之。那么大家可以思考下Java是属于编译型语言还是解释型语言呢?那为什么java不直接编译成可执行文件呢?为了实现跨平台,Java源代码被编译成字节码,然后由不同平台的虚拟机解释执行,从而实现一次编译,到处运行。跨平台效果编译原理Java语言的编译期分为前端编译和后端编译两个阶段。前端编译是指将*.java文件转换为*.class文件的过程,包括词法分析、句法分析和语义分析。中间代码的生成主要有以下几个步骤:后端编译在一些商用虚拟机中,Java程序最初是通过解释器解释执行的。当虚拟机发现某个方法或代码块运行特别频繁时,就会将这些代码识别为热代码。为了提高热点代码的执行效率,在运行时,虚拟机会将这些代码编译成与本地平台相关的机器码。完成这个任务的后端编译器叫做即时编译器(JITcompiler)反编译什么是反编译?既然Java编译是指将Java源代码编译成Java字节码的过程,那么Java反编译就简单的说就是将Java字节码翻译成源代码的过程。为什么要先反编译呢?源码是字符编码,字节码是二进制字节流,源码是给人看的,字节码是给虚拟机看的。所以,要想见人,就需要把字节码转成源码。如果你想为虚拟机执行它,你需要将源代码编译成字节码。当我们有一个class文件,想看源码的时候,可以使用反编译的方法。比如我们要理解某个Java语法糖编译,那么反编译即可;如果有人给你发了一个jar包,你需要看看里面某个类是怎么写的。遇到这种情况,可以考虑使用Java反编译反编译工具。在线反编译工具1.http://www.decompiler.com/2.http://www.javadecompilers.com/这个网站的主要优点是有多种反编译器可供选择离线反编译工具JD-GUIGitHub:https://github.com/java-decompiler/jd-gui官网:http://java-decompiler.github.io/下载后直接将class文件或jar包拖到界面即可。Luyten下载地址:https://github.com/deathmarine/Luyten/releasesArthas官网:https://arthas.aliyun.com/doc/可以使用jad命令反编译JVM中运行类的字节码成java代码。这个工具很好用,强烈推荐其他工具。javapjavap是jdk自带的一个工具,可以反编译代码,也可以直接通过javap-help查看java编译器生成的字节码查看其用法用法:javap其中,可能的选项包括:-help--help-?outputThisusagemessage-version版本信息-v-verbose输出附加信息-l输出行号和局部变量表-public只显示公共类和成员-protected显示受保护/公共类和成员-package显示包/受保护/公共类和成员(默认)-p-private显示所有类和成员-c反汇编代码-s输出内部类型签名-sysinfo显示正在处理的类的系统信息(路径、大小、日期、MD5哈希)列)-constantsshow最终常量-classpath指定查找用户类文件的位置-cp指定查找用户类文件的位置-bootclasspath覆盖引导类文件的位置基本用法:javacTest.javajavap-cTest.classjclasslibjclasslib是一个可视化的字节码查看工具,安装IDEA插件后可以直接安装,IDEA编译源码后,可以选择“View”->“ShowBytecodeWithJclasslib”来查看字节码.可以直观的看到class文件包含基本信息,常量池,接口信息,字段信息,方法信息和属性信息.方法信息还包括行号表,局部变量表,异常表,等阅读字节码指令涉及的知识很多,后面的文章会通过案例详细讲解class文件结构和字节码指令的执行过程,推荐两本很经典的书:《深入理解 Java 虚拟机》,《Java 虚拟机规范》反编译示例先看一个简单常见的案例:;为了(Stringstr:data){System.out.println(str);}}}我们直接在IDEA中编译class文件,然后在目标目录下寻找class,双击打开,得到如下反编译源码代码:publicclassForEachDemo{publicForEachDemo(){}publicstaticvoidmain(String[]args){Listdata=newArrayList();data.add("a");data.add("b");Iteratorvar2=data.iterator();while(var2.hasNext()){Stringstr=(String)var2.next();System.out.println(str);}}}从上面的反编译代码可以明显看出,当有原始代码中没有写构造函数,编译器会自动生成一个默认的构造函数;foreach循环遍历列表时,底层实现迭代器转载本文,请联系月版飞语?。