1.什么是class文件
class文件就是可以被JVM識(shí)別支竹,加載,運(yùn)行的一種文件格式券敌。一般情況下唾戚,它可以由java代碼編譯執(zhí)行后得到,但是這并不是一定的壁顶,像kotlin恤煞,scala,python,ruby等JVM語(yǔ)言都可以通過(guò)編譯得到class文件遇伞。
2.如何得到class文件
上面已經(jīng)講了,得到class文件不一定要使用java另假。這里我們只討論使用java去生成class文件础淤。一般情況下,我們都是通過(guò)Ecplise或者Intellij這樣的IDE開(kāi)發(fā)工具去build工程鬼吵,當(dāng)然也可以用個(gè)JDK中的javac命令去編譯java文件扣甲。當(dāng)我們一開(kāi)始接觸java時(shí),老師也是這么教的齿椅。這里回顧下琉挖,前提pc已經(jīng)有java環(huán)境了(安裝了jdk,配置了環(huán)境變量)
寫(xiě)個(gè)簡(jiǎn)單java代碼文件
public class HelloClass{ public static void main(String[] args){ System.out.println("Hello Class!"); } }
然后進(jìn)入終端涣脚,通過(guò)javac命令編譯這個(gè)文件
javac -target 1.6 -source 1.6 HelloClass.java
這是你就會(huì)在當(dāng)前目錄下看到一個(gè)HelloClass.class的文件示辈,這就是我們的目標(biāo)。就這么簡(jiǎn)單...
3.class文件的結(jié)構(gòu)
class文件記錄著整一個(gè)類(lèi)的所有信息遣蚀,是所有矾麻!
class文件結(jié)構(gòu)的3個(gè)特點(diǎn):
- 是一種8位字節(jié)的二進(jìn)制流文件
- 各個(gè)數(shù)據(jù)按順序緊密的排列,無(wú)間隙
- 每個(gè)類(lèi)或者借口都單獨(dú)占據(jù)一個(gè)class文件
上面就是完整的class文件的結(jié)構(gòu)芭梯,是不是看暈了...
- magic 加密字段
- minor_version 支持最低版本的jdk
- major_version 編譯使用的jdk版本
- constant_pool_count 常量池的數(shù)量
- cp_info constant_pool 常量池的結(jié)構(gòu)體险耀,數(shù)量不定
- access_flags 訪問(wèn)級(jí)別
- this_class 當(dāng)前類(lèi)
- super_class 父類(lèi)
- interfaces_count 類(lèi)實(shí)現(xiàn)接口的數(shù)量
- fields_count 類(lèi)成員變量的數(shù)量
- methods_count 類(lèi)方法的數(shù)量
- method_info methods 類(lèi)方法的結(jié)構(gòu)體
- attributes_count 類(lèi)屬性的數(shù)量
- attribute_info attributes 類(lèi)屬性的結(jié)構(gòu)體
4.什么dex文件
dex文件就是可以被android虛擬機(jī)dvm識(shí)別,加載玖喘,運(yùn)行的文件格式甩牺。
5.如何生成dex文件
一般情況下,我們都是通過(guò)IDE的build工具生成芒涡,當(dāng)然我們也可以手動(dòng)編譯生成柴灯。所需要用到的命令在android sdk路徑下的build-tools\25.0.2(任意版本)\dx,我們現(xiàn)在的目標(biāo)是要將HelloClass.class這個(gè)文件打包成dex文件
dx --dex --output HelloClass.dex HelloClass.class
然后卖漫,你就可以在當(dāng)前目錄下看到一個(gè)叫HelloClass.dex的文件,so easy赠群!
6.運(yùn)行dex文件
因?yàn)閐ex文件是運(yùn)行在android dalvik虛擬機(jī)上的羊始,所以我們要先將dex文件push到手機(jī)中,具體步驟如下:
adb push HelloClass.dex /sdcard/ adb shell 127|root@vbox86p:/sdcard # dalvikvm -cp HelloClass.dex HelloClass
然后就能看到Hello Class!的打印了查描,跟我們?cè)趐c上運(yùn)行一模一樣
7.dex文件的結(jié)構(gòu)
- 一種8位字節(jié)的二進(jìn)制流文件
- 各個(gè)數(shù)據(jù)按順序緊密排列突委,無(wú)間隙
- 整個(gè)應(yīng)用所有java源文件都放在一個(gè)dex文件中(一般情況下)
上面就是完整的dex文件的結(jié)構(gòu),我們可以把dex的文件結(jié)構(gòu)分成3個(gè)區(qū)冬三。
第一個(gè)區(qū)是header匀油,包括header_item dex_header這個(gè)結(jié)構(gòu)體,第二個(gè)區(qū)是索引區(qū)勾笆,包括string_id_list dex_string_ids(字符串索引)敌蚜,type_id_list dex_type_ids(類(lèi)型索引),proto_id_list dex_proto_ids(方法原型索引)窝爪,field_id_list dex_field_ids(域索引)弛车,method_id_list dex_method_ids(方法索引),第三個(gè)區(qū)是數(shù)據(jù)區(qū)蒲每,包括
class_def_item_list dex_class_defs(類(lèi)的定義)纷跛,data(圖中的value),link_data(so)
8.class文件和dex文件的對(duì)比#
兩者本質(zhì)上是一致的邀杏,dex文件也是從class文件演變而來(lái)的贫奠,個(gè)人感覺(jué)像是打包一樣,當(dāng)然不止如此望蜡。dex文件比class文件的優(yōu)勢(shì)是去除了class文件結(jié)構(gòu)中冗余的設(shè)計(jì)唤崭,更加精簡(jiǎn),適合于運(yùn)用在移動(dòng)端泣特。