日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
詳解Javac編譯與反編譯

Javac是一種編譯器,它的作用是將符合Java語言規(guī)范的源代碼轉(zhuǎn)化成符合Java虛擬機規(guī)范的Java字節(jié)碼,下面為大家詳細講解一下java中的編譯與反編譯。

基本概念

我們可以通過javac命令將Java程序的源代碼編譯成Java字節(jié)碼,即我們常說的class文件,這是我們通常意義上理解的編譯。但是,字節(jié)碼并不是機器語言,要想讓機器能夠執(zhí)行,還需要把字節(jié)碼翻譯成機器指令,這個過程是通過解釋器實現(xiàn)的,叫解釋執(zhí)行。注意:大家別把編譯和解釋執(zhí)行混淆了,而后面所說的后端編譯過程是JVM為提高效率做的優(yōu)化,在不同的虛擬機實現(xiàn)中,執(zhí)行引擎在執(zhí)行字節(jié)碼的時候,通常會有解釋執(zhí)行(通過解釋器執(zhí)行)和編譯執(zhí)行(通過即時編譯器產(chǎn)生本地代碼執(zhí)行)兩種選擇,也可能兩者兼?zhèn)?。所以大家可以思考下,Java到底是屬于編譯型語言還是解釋器語言呢?那為什么java不直接編譯成可執(zhí)行文件呢,其實主要還是為了實現(xiàn)跨平臺。Java源碼通過編譯成字節(jié)碼,然后通過不同平臺的虛擬機解釋執(zhí)行,從而實現(xiàn)一次編譯,到處運行的跨平臺的效果。

編譯原理

Java語言的編譯期分為前端編譯和后端編譯兩個階段

前端編譯

前端編譯是指把*.java文件轉(zhuǎn)變成*.class文件的過程,包括詞法分析、語法分析、語義分析與中間代碼生成。

主要有下面幾個步驟:

后端編譯

在部分商用虛擬機中,Java程序最初是通過解釋器進行解釋執(zhí)行的,當虛擬機發(fā)現(xiàn)某個方法或代碼塊的運行特別頻繁時,就會把這些代碼認定為熱點代碼

為了提高熱點代碼的執(zhí)行效率,在運行時, 虛擬機將會把這些代碼編譯成與本地平臺相關(guān)的機器碼

完成這個任務(wù)的后端編譯器稱為即時編譯器(JIT編譯器)

反編譯

什么是反編譯

既然Java 編譯是指將 Java 源碼編譯成 Java 字節(jié)碼的過程

那么Java 反編譯簡單說就是指根據(jù) Java 字節(jié)碼翻譯成源碼的過程

為什么要有反編譯

首先這個源碼是字符編碼,字節(jié)碼是二進制字節(jié)流,并且源碼是給人看的,字節(jié)碼是給虛擬機看的

因此如果想給人看,需要將字節(jié)碼轉(zhuǎn)為源碼。如果想給虛擬機執(zhí)行,需要將源碼編譯成字節(jié)碼,當我們有類文件想看源碼時,可以采用反編譯的方式實現(xiàn)

比如想了解某個Java 語法糖編譯后,再反編譯是什么樣的;別人給你發(fā)一個 jar 包,你需要看其中某個類是怎么寫的,等此類情況都可以考慮是用 Java 反編譯

反編譯工具

JD-GUI

GitHub :https://github.com/java-decompiler/jd-gui

官網(wǎng):http://java-decompiler.github.io/

Java編譯與反編譯Java編譯與反編譯

下載后將類文件或者 jar 包直接拖動到界面即可

Luyten

下載地址:https://github.com/deathmarine/Luyten/releases

Arthas

官網(wǎng):https://arthas.aliyun.com/doc/

可以使用 jad 命令將 JVM 中運行的 class 的 byte code 反編譯成 java 代碼

javap

javap是jdk自帶的一個工具,可以對代碼反編譯,也可以查看java編譯器生成的字節(jié)碼

直接通過javap -help查看其用法

用法: javap  
其中, 可能的選項包括:
 -help  --help  -?        輸出此用法消息
 -version                 版本信息
 -v  -verbose             輸出附加信息
 -l                       輸出行號和本地變量表
 -public                  僅顯示公共類和成員
 -protected               顯示受保護的/公共類和成員
 -package                 顯示程序包/受保護的/公共類
                          和成員 (默認)
 -p  -private             顯示所有類和成員
 -c                       對代碼進行反匯編
 -s                       輸出內(nèi)部類型簽名
 -sysinfo                 顯示正在處理的類的
                          系統(tǒng)信息 (路徑, 大小, 日期, MD5 散列)
 -constants               顯示最終常量
 -classpath         指定查找用戶類文件的位置
 -cp                指定查找用戶類文件的位置
 -bootclasspath     覆蓋引導(dǎo)類文件的位置

基本使用:

javac Test.java
javap -c Test.class

jclasslib

jclasslib 是一種可視化的字節(jié)碼查看工具,可以直接在 IDEA 插件安裝

安裝以后,在 IDEA 編譯源碼后,可以選擇 View” ->“Show Bytecode With Jclasslib即可查看字節(jié)碼

可以直觀地看到 class 文件包含基本信息、常量池、接口信息、字段信息、方法信息和屬性信息

其中方法信息又包含行號表、局部變量表,異常表等

要讀懂字節(jié)碼指令涉及的知識很多,之后的文章會通過案例詳細講解class文件結(jié)構(gòu)和字節(jié)碼指令的執(zhí)行過程

推薦兩本非常經(jīng)典的圖書:《深入理解 Java 虛擬機》、《Java 虛擬機規(guī)范》

反編譯示例

下面看一個簡單和常見的案例:

public class ForEachDemo {
   public static void main(String[] args) {

       List data = new ArrayList();
       data.add("a");
       data.add("b");

       for (String str : data) {
           System.out.println(str);
       }

   }
}

我們直接在 IDEA 對該類文件進行編譯,然后再 target 目錄中尋找該類,雙擊打開,得到下面的反編譯源碼:

public class ForEachDemo {
   public ForEachDemo() {
   }

   public static void main(String[] args) {
       List data = new ArrayList();
       data.add("a");
       data.add("b");
       Iterator var2 = data.iterator();

       while(var2.hasNext()) {
           String str = (String)var2.next();
           System.out.println(str);
       }

   }
}

從上述反編譯代碼可以清楚地看到,原始代碼中沒有編寫構(gòu)造方法時,編譯器會自動生成一個默認構(gòu)造方法;foreach 循環(huán)來遍歷 list 時,底層通過 iterator 來實現(xiàn)


網(wǎng)頁題目:詳解Javac編譯與反編譯
網(wǎng)站地址:http://m.5511xx.com/article/cdgsiii.html