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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Java編譯和反編譯那些事

前言

專業(yè)從事網(wǎng)站建設(shè)、做網(wǎng)站,高端網(wǎng)站制作設(shè)計(jì),小程序設(shè)計(jì),網(wǎng)站推廣的成都做網(wǎng)站的公司。優(yōu)秀技術(shù)團(tuán)隊(duì)竭力真誠(chéng)服務(wù),采用H5開發(fā)+CSS3前端渲染技術(shù),響應(yīng)式網(wǎng)站開發(fā),讓網(wǎng)站在手機(jī)、平板、PC、微信下都能呈現(xiàn)。建站過(guò)程建立專項(xiàng)小組,與您實(shí)時(shí)在線互動(dòng),隨時(shí)提供解決方案,暢聊想法和感受。

挺久沒更文章了,之前有一個(gè)月在面試,后來(lái)寫了篇面經(jīng),有一些朋友找我交流問題,所以一直沒時(shí)間寫技術(shù)文章,估計(jì)以后更新文章頻率不會(huì)那么高了,不過(guò)還是會(huì)定期分享的,我的目的還是希望我的每篇文章大家都能學(xué)到點(diǎn)東西

基本概念

我們可以通過(guò)javac命令將Java程序的源代碼編譯成Java字節(jié)碼,即我們常說(shuō)的class文件,這是我們通常意義上理解的編譯

但是,字節(jié)碼并不是機(jī)器語(yǔ)言,要想讓機(jī)器能夠執(zhí)行,還需要把字節(jié)碼翻譯成機(jī)器指令,這個(gè)過(guò)程是通過(guò)解釋器實(shí)現(xiàn)的,叫解釋執(zhí)行

注意:大家別把編譯和解釋執(zhí)行混淆了,而后面所說(shuō)的后端編譯過(guò)程是JVM為提高效率做的優(yōu)化

在不同的虛擬機(jī)實(shí)現(xiàn)中,執(zhí)行引擎在執(zhí)行字節(jié)碼的時(shí)候,通常會(huì)有解釋執(zhí)行(通過(guò)解釋器執(zhí)行)和編譯執(zhí)行(通過(guò)即時(shí)編譯器產(chǎn)生本地代碼執(zhí)行)兩種選擇,也可能兩者兼?zhèn)?/p>

所以大家可以思考下,Java到底是屬于編譯型語(yǔ)言還是解釋器語(yǔ)言呢

那為什么java不直接編譯成可執(zhí)行文件呢

為了實(shí)現(xiàn)跨平臺(tái)

Java源碼通過(guò)編譯成字節(jié)碼,然后通過(guò)不同平臺(tái)的虛擬機(jī)解釋執(zhí)行,從而實(shí)現(xiàn) 一次編譯,到處運(yùn)行的跨平臺(tái)的效果

編譯原理

Java語(yǔ)言的編譯期分為前端編譯和后端編譯兩個(gè)階段

前端編譯

前端編譯是指把*.java文件轉(zhuǎn)變成*.class文件的過(guò)程

包括詞法分析、語(yǔ)法分析、語(yǔ)義分析與中間代碼生成

主要有下面幾個(gè)步驟:

后端編譯

在部分商用虛擬機(jī)中,Java程序最初是通過(guò)解釋器進(jìn)行解釋執(zhí)行的,當(dāng)虛擬機(jī)發(fā)現(xiàn)某個(gè)方法或代碼塊的運(yùn)行特別頻繁時(shí),就會(huì)把這些代碼認(rèn)定為熱點(diǎn)代碼

為了提高熱點(diǎn)代碼的執(zhí)行效率,在運(yùn)行時(shí), 虛擬機(jī)將會(huì)把這些代碼編譯成與本地平臺(tái)相關(guān)的機(jī)器碼

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

反編譯

什么是反編譯

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

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

為什么要有反編譯

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

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

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

反編譯工具

在線反編譯工具

1.http://www.decompiler.com/

2.http://www.javadecompilers.com/,該網(wǎng)站的主要優(yōu)勢(shì)在于有多種反編譯器可供選擇

離線反編譯工具

JD-GUI

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

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

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

 
 
 
 
  1. Luyten 

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

 
 
 
 
  1. Arthas 

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

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

這個(gè)工具很好用,強(qiáng)烈推薦

其他工具

javap

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

直接通過(guò)javap -help查看其用法

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

基本使用:

 
 
 
 
  1. javac Test.java 
  2. javap -c Test.class 

jclasslib

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

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

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

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

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

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

反編譯示例

下面看一個(gè)簡(jiǎn)單和常見的案例:

 
 
 
 
  1. public class ForEachDemo { 
  2.     public static void main(String[] args) { 
  3.  
  4.         List data = new ArrayList<>(); 
  5.         data.add("a"); 
  6.         data.add("b"); 
  7.  
  8.         for (String str : data) { 
  9.             System.out.println(str); 
  10.         } 
  11.  
  12.     } 

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

 
 
 
 
  1. public class ForEachDemo { 
  2.     public ForEachDemo() { 
  3.     } 
  4.  
  5.     public static void main(String[] args) { 
  6.         List data = new ArrayList(); 
  7.         data.add("a"); 
  8.         data.add("b"); 
  9.         Iterator var2 = data.iterator(); 
  10.  
  11.         while(var2.hasNext()) { 
  12.             String str = (String)var2.next(); 
  13.             System.out.println(str); 
  14.         } 
  15.  
  16.     } 

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

本文轉(zhuǎn)載自微信公眾號(hào)「月伴飛魚」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系月伴飛魚公眾號(hào)。


分享名稱:Java編譯和反編譯那些事
當(dāng)前網(wǎng)址:http://m.5511xx.com/article/cdodchi.html