每个人都注定要体验生命的美好,也要体验其不可避免的暗黑之处:幻灭、衰老、疾病、孤独、丧失、无意义、痛苦的选择和死亡
基本概念
我们可以通过javac命令将Java程序的源代码编译成Java字节码,即我们常说的class文件,这是我们通常意义上理解的编译
但是,字节码并不是机器语言,要想让机器能够执行,还需要把字节码翻译成机器指令,这个过程是通过解释器实现的,叫解释执行
注意:大家别把编译和解释执行混淆了,而后面所说的后端编译过程是JVM为提高效率做的优化
在不同的虚拟机实现中,执行引擎在执行字节码的时候,通常会有解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,也可能两者兼备
所以大家可以思考下,Java到底是属于编译型语言还是解释器语言呢
那为什么java不直接编译成可执行文件呢
为了实现跨平台
Java源码通过编译成字节码,然后通过不同平台的虚拟机解释执行,从而实现 一次编译,到处运行的跨平台的效果
编译原理
Java语言的编译期分为前端编译和后端编译两个阶段
前端编译
前端编译是指把*.java文件转变成*.class文件的过程
包括词法分析、语法分析、语义分析与中间代码生成
主要有下面几个步骤:
后端编译
在部分商用虚拟机中,Java程序最初是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为热点代码
为了提高热点代码的执行效率,在运行时, 虚拟机将会把这些代码编译成与本地平台相关的机器码
完成这个任务的后端编译器称为即时编译器(JIT编译器)
反编译
什么是反编译
既然Java 编译是指将 Java 源码编译成 Java 字节码的过程
那么Java 反编译简单说就是指根据 Java 字节码翻译成源码的过程
为什么要有反编译
首先这个源码是字符编码,字节码是二进制字节流,并且源码是给人看的,字节码是给虚拟机看的
因此如果想给人看,需要将字节码转为源码。如果想给虚拟机执行,需要将源码编译成字节码,当我们有类文件想看源码时,可以采用反编译的方式实现
比如想了解某个 Java 语法糖编译后,再反编译是什么样的;别人给你发一个 jar 包,你需要看其中某个类是怎么写的,等此类情况都可以考虑是用 Java 反编译
反编译工具
在线反编译工具
1.http://www.decompiler.com/
2.http://www.javadecompilers.com/,该网站的主要优势在于有多种反编译器可供选择
离线反编译工具
JD-GUI
GitHub :http://github.com/java-decompiler/jd-gui官网:http://java-decompiler.github.io/
下载后将类文件或者 jar 包直接拖动到界面即可
Luyten
下载地址:http://github.com/deathmarine/Luyten/releases
Arthas
官网:http://arthas.aliyun.com/doc/
可以使用 jad 命令将 JVM 中运行的 class 的 byte code 反编译成 java 代码这个工具很好用,强烈推荐
其他工具
javap
javap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码直接通过javap -help查看其用法
用法: javap