Java字節碼方法表與屬性表深度剖析

方法表:

在上一次咱們已經分析到了字段信息了,如下:

緊接著就是方法相關的信息了:

而它展開之后的結構為:

所以往后數2個字節,看一下方法的總數:

3個方法,可咱們只定義了兩個方法呀:

因為編譯器會為我們生成一個默認的構造方法,所以就3個了,那每個方法的具體信息是啥呢?它是一個method_info類型的,如下:

也就是方法表,當然也有它自己的一個結構,下面來看一下:

  • access_flags:占用兩個字節,表示訪問標記。
  • name_index:占用兩個字節,名字索引,指向的是常量池。
  • descriptor_index:占用兩個字節,描述索引,指賂的是常量池。
  • attributes_count:占用兩個字節,屬性個數,如果為0,則下面的屬性表就不顯示了。
  • attributes::屬性表。

用結構形式來表示:

那按照上面的表先來看第一個方法的訪問標記,往后讀兩個字節:

查看下訪問修飾符表,對應于:

表示是一個public的方法,接下來兩個字節則表示方法名字索引,走著:

對應常量池:

再往下二個字節則表示描述符索引:

對應常量池:

說明該方法是一個默認構造方法。從javap -verbose中也能對應上:

屬性表:

接下來二個字節為屬性個數:

表示有一個屬性,所以屬性表中的個數也為1,而屬性表是attribute_info類型,很顯然也有它自己的結構,那長啥樣呢?

  • attribute_name_index:占2個字節,表示屬性名字的索引,指向常量池。
  • attribute_length:占4個字節,表示屬性的長度。
  • info[attribute_length]:占1個字節,表示具體的信息。

依照上面的順序,先數2個字節:

對應常量池:

其實在javap -verbose中也能看到每個方法都有一個Code字樣,如下:

Constant pool:#1 = Methodref          #4.#20         // java/lang/Object."<init>":()V#2 = Fieldref           #3.#21         // com/jvm/bytecode/MyTest1.a:I#3 = Class              #22            // com/jvm/bytecode/MyTest1#4 = Class              #23            // java/lang/Object#5 = Utf8               a#6 = Utf8               I#7 = Utf8               <init>#8 = Utf8               ()V#9 = Utf8               Code#10 = Utf8               LineNumberTable#11 = Utf8               LocalVariableTable#12 = Utf8               this#13 = Utf8               Lcom/jvm/bytecode/MyTest1;#14 = Utf8               getA#15 = Utf8               ()I#16 = Utf8               setA#17 = Utf8               (I)V#18 = Utf8               SourceFile#19 = Utf8               MyTest1.java#20 = NameAndType        #7:#8          // "<init>":()V#21 = NameAndType        #5:#6          // a:I#22 = Utf8               com/jvm/bytecode/MyTest1#23 = Utf8               java/lang/Object
{public com.jvm.bytecode.MyTest1();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: aload_05: iconst_16: putfield      #2                  // Field a:I9: returnLineNumberTable:line 3: 0line 4: 4LocalVariableTable:Start  Length  Slot  Name   Signature0      10     0  this   Lcom/jvm/bytecode/MyTest1;public int getA();descriptor: ()Iflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: getfield      #2                  // Field a:I4: ireturnLineNumberTable:line 7: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/jvm/bytecode/MyTest1;public void setA(int);descriptor: (I)Vflags: ACC_PUBLICCode:stack=2, locals=2, args_size=20: aload_01: iload_12: putfield      #2                  // Field a:I5: returnLineNumberTable:line 11: 0line 12: 5LocalVariableTable:Start  Length  Slot  Name   Signature0       6     0  this   Lcom/jvm/bytecode/MyTest1;0       6     1     a   I
}
SourceFile: "MyTest1.java"

那它表示啥意思呢?其實是表示方法執行的代碼,指的是:

當然啦在字節碼文件中不可能是跟源文件中看到的一樣,而是通過了一些助記符進行了處理,如下:

這個在未來進行詳細學習的,好,繼續來分析屬性,接下來4個字節表示屬性的長度,如下:

說明屬性的長度為56,然后最后一個字節表示info信息,也就是code的具體信息,這塊是比較復雜的,下面先來了解一些理論:

  • JVM預定義了部分attribute,但是編譯器自己也可以實現自己的attribute寫入class文件里,供運行時使用。
  • 不同的attribute通過attribute_name_index來區分。

其中JVM預定義的attribute為如下表:

Code結構:

這部分東東是比較多的,這次只先對其結構有個初步了解既可,它的作用是保存該方法的結構,如所對應的字節碼:

  • attribute_length表示attribute所包含的字節數,不包含attribute_name_index和attribute_length字段。
  • max_stack表示這個方法運行的任何時刻所能達到的操作數棧的最大深度。
  • max_locals表示方法執行期間創建的局部變量的數目,包含用來表示傳入的參數的局部變量。
  • code_length表法該方法所包含的字節碼的字節數以及具體的指令碼。
  • 具體的字節碼既是該方法被調用時,虛擬機所執行的字節碼。
  • exception_table:這里存放的是處理異常的信息。
  • 第一個exception_table表項由start_pc、end_pc、handler_pc、catch_type組成。
  • start_pc和end_pc表示在code數組中的從start_pc到end_pc處(包含start_pc,不包含end_pc)的指令拋出的異常會由這個表項來處理。
  • handler_pc表示處理異常的代碼的開始處。catch_type表示會被處理的異常類型,它指向常量池里的一個異常類。當catch_type為0時,表示處理所有的異常。

這么多陌生的字段,直接暈掉,木要著急,先有個大概了解,在未來學習中會吃透它的,好,先來回到字節碼中繼續分析,其中code中屬性的長度為56:

接下來2個字節表示max_stack:

再接下來2個字節表示max_locals:

對應javap -verbose:

接下來4個字節表示code的長度:

code_length=10,而此時發現在javap -verbose中貌似木有找到對應的:

那接下來的分析沒有了參照就不知道我們自己分析的對不對了,對于學習效果會大打折扣了,此時就得借助于另外一個工具來參照了,該工具為jclasslib,gitbub地址:https://github.com/ingokegel/jclasslib,它顯示的信息就會比javap -verbose要詳細很多,訪問一下官網:

它包含獨立的軟件和IntelliJ IDEA插件化的方式,所以都裝一下,先下載mac安裝包:

?

具體安裝就不概述了,裝好之后用它來打開我們的字節碼文件既可,長這樣:

同時可以給IDE裝上插件,更加便于分析,如下:

安裝好之后,直接就可以在當前打開的java文件中執行這個菜單選項既可:

看到的效果跟獨立的軟件看到的是一樣的,好,下面來用這個新工具來瞅一眼看到的信息:

對比下javap -verbose:

差不多,不過jclasslib工具可以看到JDK的版本,接下來就是常量池:

但實際是只有23個,展開看一下:

對于javap -versbose:

明顯要豐富許多,繼續往下看:

其中是可以直接點擊鏈到對應的常量池的,如下:

接著就是常量池的信息了:

展開之后,索引都能鏈接上去,非常之方便:

接著就是接口信息,目前木有接口:

然后就到了字段信息了,目前只有一個字段:

然后再是方法信息,有三個方法:

點擊其中一個看一下:

有code信息:

跟javap -versbose是對應上的:

最后是附加信息:

LineNumberTable:這個屬性用來表示code數組中的字節碼和Java代碼行數之間的關系。這個屬性可以用來在調試的時候定位代碼執行的行數。比如說程序拋異常了,而程序執行的是字節碼文件,怎么我們就能看到具體報錯在源碼中的行數呢,其實就是通過該信息做到的。

而它的結構體為:

跟javap -verbose中是能對應上的:

最后則是類的屬性了:

可見jclasslib的結構跟咱們理論上看到的是一模一樣的,所以有了它也能讓我們在未來學習code這塊的結構更加清晰,這是javap -verbose不能達到的。

轉載于:https://www.cnblogs.com/webor2006/p/9459681.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279648.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279648.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279648.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

最大連續子數組和與JUnit測試

【題目】最大連續子數組和&#xff08;最大子段和&#xff09; 背景 問題&#xff1a; 給定n個整數&#xff08;可能為負數&#xff09;組成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]a[i1]…a[j]的子段和的最大值。當所給的整數均為負數時定義子段和為0&#xff0c;依此定義…

筆記本電源適配器為什么總壞_為什么某些交流適配器和電源會發出嘯叫聲?

筆記本電源適配器為什么總壞Most of the time our AC adapters and power supplies tend to be quiet, but what does it mean when one makes a whining noise? Should you be concerned? Today’s SuperUser Q&A post has the answers to a worried reader’s question…

4412 字符類設備的設備號

一、靜態申請字符類設備號 字符類設備函數在文件"include/linux/fs.h"中內核提供了三個函數來注冊一組字符設備編號&#xff0c;這三個函數分別是 register_chrdev_region()alloc_chrdev_region()register_chrdev()register_chrdev_region()是提前知道設備的主次設備…

monogdb操作system.*權限

mongodb roles system.roles集合刪不掉 當你自定義了特權(角色): db.createRole({role: "dropSystemViewsAnyDatabase",privileges: [{actions: [ "dropCollection" ],resource: { db: "", collection: "system.roles" }}],roles: []}…

如何發現假庫存照片(并將合適的人歸于屬性)

Spammers and other unscrupulous advertisers are always looking for new ways to get you click on their pages. One of the latest tactics is to steal popular and useful stock images—like the kind you sometimes see in news articles—and re-upload them elsewhe…

Mysql Hunter

一、簡介自動化實施的過程中&#xff0c;我們通常都面臨一個棘手的問題&#xff1a;數據的準備和恢復。即在成功執行一個自動化用例時&#xff0c;我們可能需要一定的數據前提&#xff0c;而為了使得整個前提不至于被其他的用例破壞&#xff0c;以至于我們有時不得不在自動化用…

C6748_UART(5) - UART寄存器

1、FIFO控制寄存器&#xff08;FCR&#xff09;RXFIFTL&#xff1a;接收FIFO中斷觸發(當FIFO中的數據量剛到達所要求&#xff08;trigger level&#xff09;的時候會產生中斷);DMAMODE1:如果FIFO使能的話此位可以使能DMA模式。TXCLR&#xff1a;發送FIFO清除。RXCLR&#xff1a…

如何在Windows 10上限制Wi??ndows Update的下載帶寬

Windows 10’s Fall Creators Update gives you more control of Windows Update’s downloads and uploads. You can now set a download bandwidth limit, ensuring Windows Update won’t hog your Internet connection with its background downloads. Windows 10的Fall Cr…

Elasticsearch嵌套查詢

2019獨角獸企業重金招聘Python工程師標準>>> 一、背景 最近在做基于宴會廳檔期的商戶搜索推薦時&#xff0c;如果用傳統平鋪式的mapping結構&#xff0c;無法滿足需求場景&#xff0c;于是用到了Elasticsearch支持的Nested(嵌套)查詢。 二、普通對象與嵌套對象的索引…

寫給深圳首期Python自動化開發周未班的信

你是否做了正確的決定&#xff1f; 深圳首期周未班的同學們大家好&#xff0c;我是Alex, 老男孩教育的聯合創始人&#xff0c;Python項目的發起人&#xff0c;51CTO學院連續2屆最受學員喜愛的講師&#xff0c;中國最早一批使用Python的程序員&#xff0c;當然還有一堆頭銜&…

網站跳出率的相關要點介紹

今天小峰seo博客和大家一起來探討關于“網站跳出率的相關要點”&#xff0c;這里大體是分為三大要點&#xff1a;首先是進入的流量渠道&#xff0c;然后就是綜合流量速度和內容的質量問題&#xff0c;細的來說就是我們的網站進來的用戶是搜索什么關鍵詞來的是通過百度還是搜狗或…

如何使用PowerShell提升開發效率(以Windows Embedded CE為例)

簡介 本文講述如何使用Powershell通過RAPI來控制Windows Embedded CE和Windows Mobile設備。 緣由 我入行的時候是做AS400 RPG和UNIX C開發的&#xff0c;所有開發環境都是字符界面&#xff0c;因此習慣了vigrepmake的開發模式。后來開始做Windows的開發&#xff0c;開始也不大…

視頻圖像傳輸學習筆記-基礎小知識(一)

攝像頭DVP與MIPI區別 DVP是并口&#xff0c;需要PCLK、VSYNC、HSYNC、D[0&#xff1a;11]——可以是8/10/12bit數據&#xff0c;看ISP或baseband是否支持&#xff1b;總線PCLK極限大約在96M左右&#xff0c;而且走線長度不能過長&#xff0c;所有DVP最大速率最好控制在72M以…

java程序員面試交流項目經驗

粘貼自&#xff1a;https://blog.csdn.net/wangyuxuan_java/article/details/8778211 1&#xff1a;請你介紹一下你自己 這是面試官常問的問題。一般人回答這個問題過于平常&#xff0c;只說姓名、愛好、工作經驗&#xff0c;這些簡歷上都有。其實&#xff0c;面試官最希望知道…

Windows7旗艦版磁盤分區詳解—附分區步驟截圖

最近工作中配置使用聯想的Thinkpad TL系列本本.當然原裝的系統時剛發布的Windows RTM旗艦版.在考慮買之前也參考了戴爾 蘋果的等等, 但個人私下也是一直在用Tinkpad系列, 相比其他的品牌本人還是比較鐘情于Tinkpad 非常實用的鍵盤. 以及簡潔的外觀.買回來一看這個TL系列原裝的系…

outlook存檔郵件_如何在Outlook 2013中存檔電子郵件

outlook存檔郵件We’ve always been told that backing up our data is a good idea. Well, that same concept can extend to email as well. You may want to archive your email every so often, such as monthly, quarterly, or even yearly. 我們一直被告知備份數據是一個…

洛谷 P1736 創意吃魚法(多維DP)

題目描述 回到家中的貓貓把三桶魚全部轉移到了她那長方形大池子中&#xff0c;然后開始思考&#xff1a;到底要以何種方法吃魚呢&#xff08;貓貓就是這么可愛&#xff0c;吃魚也要想好吃法 ^_*&#xff09;。她發現&#xff0c;把大池子視為01矩陣&#xff08;0表示對應位置無…

計算機組裝和維護_如何構建自己的計算機,第二部分:組裝在一起

計算機組裝和維護So you’ve selected your parts, double- and triple-checked their compatibility, and waited for economy shipping to bring them all to your door. It’s time to get to the fun part: putting them all together. 因此&#xff0c;您已經選擇了零件&a…

Python學習-集合的常見用法

st [1,2,3,4,5] ct [2,3,4,5,76] list set(["name", list, try]) list2 set(["name", list, try, but, test]) # 兩個列表去重&#xff0c;利用集合st set(st) #設為集合 ct set(ct) print(st, type(st))sct0 st.union(ct) #并集 sct st | ct …

Autofac之自動裝配

從容器中的可用服務中選擇一個構造函數來創造對象&#xff0c;這個過程叫做自動裝配。這個過程是通過反射實現的 默認 思考這么一個問題,如果注冊類型中存在多個構造函數,那么Autofac會選擇哪一個來創建類型的實例 答案是"盡可能最多參數" class ConstructorClass {p…