java編程學習:深入理解JVM之Java字節碼文件

Java是一種可以撰寫跨平臺應用軟件的面向對象的程序設計語言。Java 技術具有卓越的通用性、高效性、平臺移植性和安全性,廣泛應用于PC、數據中心、游戲控制臺、科學超級計算機、移動電話和互聯網,同時擁有全球最大的開發者專業社群。

給你學習路線:html-css-js-jq-javase-數據庫-jsp-servlet-Struts2-hibernate-mybatis-spring4-springmvc-ssh-ssm

每一個class字節碼文件都唯一對應一個類或接口,class文件中記錄中類或接口的基本信息,但反之不成立,不是每一個類或接口都有一個唯一對應的字節碼文件,首先類或接口的字節碼可以不以文件的方式存儲,可以直接從內存中生成字節碼,而不產生.class文件,動態代理的原理就是直接內存中生成字節碼流,根據加載字節碼流進行類加載操作,類實例化,生成代理對象。

小編推薦一個學Java的學習裙【 七六零,二五零,五四一 】,無論你是大牛還是小白,是想轉行還是想入行都可以來了解一起進步一起學習!裙內有開發工具,很多干貨和技術資料分享!

字節碼文件記錄的信息:魔術,class文件主次版本,常量池數量及常量池表,類或接口的訪問標志,類索引,超類索引,接口數量及接口表,字段數量及字段表,方法數量及方法表,屬性屬性及屬性表,jvm中使用類c結構體表示每一種屬性,結構體中類型種類有兩種,無符號數及表,以 _info結尾表示表,以 u1,u2,u4,u8分別表示1字節,2字節,4字節,8字節無符號數

ClassFile{

u4 magic;

u2 minor_version;

u2 major_version;

u2 constant_pool_count;

cp_info constant_pool[constant_pool_count];

u2 acc_flags;

u2 this_class;

u2 super_class;

u2 interfaces_count;

u2 interfaces[interfaces_count];

u2 fields_count;

field_info fields[fields_count];

u2 methods_count;

method_info methods[methods_count];

u2 attributes_count;

attribute_info attributes[attributes_count];

}

魔術:四個字節,用于定義此字節碼文件是否符合虛擬機規范,保證字節碼文件不會威脅虛擬機的安全,若為cafebabe則表示字節碼符合虛擬機規范

主次版本號:四個字節,前兩字節表示次版本號,后兩字節表示主版本號,用于定義編譯的字節碼文件格式版本,低版本虛擬機拒絕運行高版本字節碼文件,但高版本虛擬機會向下兼容低版本字節碼文件

常量池數量及常量池表:這部分主要統計類或接口的字面量和符號引用,用于每個類或接口擁有的字面量和符號引用屬性不一定相同,所有需要兩個字節的長度來表示常量池數目,常量池數目計數從1開始,比如類或接口中總共有兩個字面量符號引用,則常量池數目為2,注意,不是從0開始計數,0可能另有用處,可以用來表示類或接口中未出現的引用,用來表示超級父類java.long.Object全限定名的索引,常量池表是一個數組,一共有18種類型,每一種類型有一個tag屬性與之對應,constant_utf8_info用于表示文本字符串,類和接口全限定名,字段名稱及描述符,方法名稱及描述符等常量信息,constant_integer_info用于存儲int類型的常量信息,只存儲int類型的值,不存儲其他符合引用信息,比如 final int a=1 符號引用信息為a,值為1,constant_float_info用于存儲float類型常量信息,也是只存儲float值,不存儲引用信息,constant_long_info用于存儲long類型的常量信息,constant_double_info用于存儲double類型的常量信息,constant_class_info用于存儲指向常量池列表constant_unf8_info類和接口全限定名的有效引用,constant_string_info用于存儲指定常量池列表constant_utf8_info某常量項的有效索引,指向文本字符串,constant_fieldref_info用于存儲指向常量池列表constant_class_info常量項和constant_nameandtype_info常量項的有效索引,constant_methodref_info用于存儲指向常量池列表constant_class_info常量項和constant_nameandtype_info常量項的有效索引,constant_interfacemethodref_info用于存儲指向常量池列表constant_class_info常量項和constant_nameandtype_info常量項的有效索引,constant_nameandtype_info用于存儲指向常量池列表constant_utf8_info常量項的有效索引,可以通過所有找到對應類及描述符,constant_methodtype_info用于存儲指向常量池constant_utf8_info常量項,表示方法類型,找到對應的方法描述符,constant_methodhandle_info用于表示方法句柄,屬性reference_kind表示方法句柄的類型,1-4表示為字段創建的方法句柄,5-8表示為類方法(構造、實例、靜態)創建的句柄,9表示為接口方法創建的句柄,reference_index屬性指向根據reference_kind對應的常量池列表,constant_invokedynamic_info用于存儲當前字節碼文件中引導方法bootstrap_method數組的有效索引和指向常量池constant_nameandtype_info常量項的有效索引

constant_utf8_info{

u1 tag;

u2 length;

u1 bytes[length];

}

constant_integer_info{

u1 tag;

u4 bytes;

}

constant_float_info{

u1 tag;

u4 float;

}

constant_long_info{

u1 falg;

u8 long;

}

constant_double_info{

u1 tag;

u4 double;

}

constant_class_info{

u1 tag;

u2 name_index;

}

constant_string_info{

u1 tag;

u2 string_index;

}

constant_fieldref_info{

u1 tag;

u2 class_index;

u2 name_and_type_index;

}

constant_mathodref_info{

u1 tag;

u2 class_index;

u2 name_and_type_index;

}

constant_interfacemathodref_info{

u1 tag;

u2 class_index;

u2 name_and_type_index;

}

小編推薦一個學Java的學習裙【 七六零,二五零,五四一 】,無論你是大牛還是小白,是想轉行還是想入行都可以來了解一起進步一起學習!裙內有開發工具,很多干貨和技術資料分享!

constant_nameandtype_info{

u1 tag;

u2 class_index;

u2 descriptor_index;

}

constant_methodhandle_info{

u1 tag;

u2 reference_kind;

u2 reference_index;

}

constant_methodtype_info{

u1 tag;

u2 descriptor_index;

}

constant_invokedynamic_info{

u1 tag;

u2 bootstrap_method_attr_index;

u2 name_and_type_index;

}

訪問標志:兩個字節,用于定義字節碼文件所表示的類或接口的訪問權限,如判斷是類還是接口,類是否被abstract修飾,類是否被final修飾, acc_interface表示是接口,acc_annotation表示是注解類型,acc_enum表示是枚舉類型,acc_public 表示類或接口是public訪問權限,acc_final表示類不允許被繼承,acc_abstract表示類為抽象類,acc_super表示類調用實例方法時需進行特殊操作

類索引及父類索引:四個字節,用于存儲指向常量池constant_class_info對應的有效索引,而constant_class_info存儲常量池列表的constant_utf8_info常量項索引,根據此索引可找到類和父類的全限定名

接口數量及接口表:接口屬性用于存儲當前類或接口的直接超類接口數量,接口表是一個數組,記住,只有常量池表從1開始計數,其余都是從數組下表0開始計數,接口表數組的每一個數組元素存儲此類或接口的直接超類接口的有效索引,根據此索引找到constant_class_info對應的常量項,根據constant_class_info可找到對應直接超類接口的全限定名

字段數量及字段表:字段數量用于存儲類或接口的字段數目,包括類字段和實例字段,字段表為一個數組,每一個數組元素都相當于一個field_info結構的對象,field_info結構包含字段完整信息:字段標識符,字段訪問修飾符,字段是類字段還是實例字段,字段是否為常量等,注意:此處字段表示當前類或接口的字段,不包括從超類或接口繼承的字段,java語法規范不允許同一個類或接口中出現同一字段名的不同字段,但是class文件中卻可以允許出現相同字段名的不同字段,只有字段的描述符不同即可,field_info結構屬性:access_flags用于存儲字段的訪問標志,acc_private,acc_protected,acc_public,acc_final,acc_static,acc_volatile等,注意:acc_final與acc_volatile不能同時出現在同一字段,name_index指向常量池constant_utf8_info常量項的有效索引,獲取當前字段的簡單名稱,descriptor_index指向常量池constant_utf8_info常量項的有效索引,獲取當前字段的描述符,attribute_count,attributes[attributes_count]這兩項表示字段的屬性信息,用于描述字段相關信息,attribute數組每一個元素都是一個attribute_info結構的元素

field_info{

u2 access_flags;

u2 name_index;

u2 descriptor_index;

u2 attributes_count;

attribute_info attributes[attribuyes_count];

}

方法數量及方法表:方法數量用于存儲當前類或接口的方法數目,包括實例方法,類方法,抽象方法,方法表是一個數組,每一個數組元素都是一個method_info結構,method_info結構包含方法的完整信息:方法描述符,訪問修飾符,是否為final方法,是否為abstract方法等,注意:此處的方法數組只是表示當前類或接口的所有方法,并不包括從超類及父接口繼承來的方法,java語法規范java類或接口中不允許出現方法簽名完全一樣的方法同時出現,會編譯報錯,而字節碼層面卻允許方法簽名完全相同的方法同時出現,只需要保證方法的返回值類型不同,method_info結構屬性與field_info一致,但acc_flags類型不盡相同,注意acc_abstract不能與acc_final,acc_static,acc_private,acc_synchronized,acc_native同時使用,接口方法中只能使用acc_public,acc_abstract,此處我有一個疑問,接口中default方法有沒有對應的訪問標志,注意:方法只能使用acc_private,acc_protected,acc_public訪問標志

method_info{

u2 access_flags;

u2 name_index;

u2 descriptor_index;

u2 attributes_count;

attribute_info attributes[attribuyes_count];

}

屬性數量及屬性表:屬性數量表示當前字節碼文件中attribute_info表數目,屬性表是一個數組,每一個數組元素都是attribute_info結構,attribute_info結構表示屬性的完整信息:第一項指向常量池constant_utf8_info某常量項的有效索引,根據此索引可找到屬性對應名稱,屬性可以出現在classFile,字段表,方法表中,用以描述相關信息,attribute_info結構完整信息:attribute_name_index指向常量池constant_utf8_info常量項的有效索引,獲取屬性名稱,attribute_length用于指明info數組長度,info[attribute_length]用于存儲屬性的數據信息,必須實現的數據信息:Code,ConstantValue,Exceptions, code屬性用于描述method_info的具體相關信息,attribute_name_index指向常量池constant_utf8_info常量項的有效索引,獲取屬性名稱,即code,attribute_length表示attribute表示attribute_info長度,不包括attribute_name_index和attribute_length的初始6字節,max_stack描述當前方法最大棧深度,max_locals描述當前方法的局部變量表,code_length表示code數組長度,code[]表示當前方法編譯后的字節碼, ContantVaue位于field_info結構中,用于通知虛擬機對類變量進行初始化,即字段需要被acc_static修飾,當前類常量不需要ContantValue通知虛擬機執行初始化,早就執行好了,實例字段此時不需要初始化

attribute_info{

u2 attribute_name_index;

u4 attribute_length;

u1 info[attribute_length];

}

code_attribute{

u2 attribute_name_index;

u4 attribute_length;

u2 max_stack;

u2 max_locals;

u4 code_length;

u1 code[code_length];

u2 exception_table_length;

exception_info exception_table[exception_table_length];

u2 attributes_count;

attribute_info attributes[attributes_count];

}

constantvalue_attribute{

u2 attribute_name_index;

u4 attribute_length;

u2 constantvalue_index;

}

小編推薦一個學Java的學習裙【 七六零,二五零,五四一 】,無論你是大牛還是小白,是想轉行還是想入行都可以來了解一起進步一起學習!裙內有開發工具,很多干貨和技術資料分享!

簡單名稱與描述符:

簡單名稱是指字段或方法的簡單的一種描述,比如person class:private String name字段簡單名稱為name,Object class:public String toString()方法簡單名稱為toString,注意:字段或方法簡單名稱不允許出現 . : / [ 等ASSIC或Unicode字符表示形式

描述符一般指字段或方法的類型,字段描述符表示字段類型描述,方法描述符表示參數描述與返回值描述,如:person class:private String name字段描述符為Ljava.lang.String,com.test.Person class:setName(String name)方法描述符為(Ljava.lang.String)V,注意:其中V表示返回值為void類型,如果參數為void則表示為()Ljava.lang.Object,表示無參的返回值為java.lang.Object引用類型的方法描述符

字段描述符解釋:B byte 字節類型,Z boolean 布爾類型,C char 字符類型,S short 短整型,I 整型,L long 長整型,F float 單進度浮點類型,D double 雙精度浮點類型,L reference 對象引用類型,[ reference 數組引用類型

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,076評論 2 375

推薦閱讀更多精彩內容