《Java虛擬機原理圖解》六、 class文件中的方法表集合--method方法在class文件中是怎樣組織的

<div class="htmledit_views" id="content_views">html

<h3><a name="t0"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">0. 前言</span></h3> <p>&nbsp;<span style="font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 瞭解JVM虛擬機原理是每個Java程序員修煉的必經之路。可是因爲JVM虛擬機中有不少的東西講述的比較寬泛,在當前接觸到的關於JVM虛擬機原理的教程或者博客中,絕大部分都是充斥的文字性的描述,很難給人以形象化的認知,看完以後感受仍是稀裏糊塗的。<br></span></p> <p><span style="font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 感於以上的種種,我打算把我在學習JVM虛擬機的過程當中學到的東西,結合本身的理解,總結成《Java虛擬機原理圖解》 這個系列,以圖解的形式,將抽象的JVM虛擬機的知識具體化,但願可以對想了解Java虛擬機原理的的Java程序員 提供點幫助。</span></p> <blockquote><fieldset><legend>讀完本文,你將會學到:</legend> <p><strong>一、類中定義的method方法是如何在class文件中組織的</strong></p> <p><strong>二、method方法的表示-方法表集合在class文件的什麼位置</strong></p> <p><strong>三、<span style="font-family:'Comic Sans MS';">類中的method方法的實現代碼---即機器碼指令存放到哪了,並初步瞭解機器指令</span></strong></p> <p><strong><span style="font-family:'Comic Sans MS';">4. 爲何沒有在類中定義本身的構造函數,卻可使用new ClassName()構造函數建立對象</span></strong></p> <p><strong><span style="font-family:'Comic Sans MS';">5. IDE代碼提示功能的基本原理<br></span></strong></p> </fieldset><br><p></p> </blockquote> <h3><a name="t1"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">1.概述</span></h3> <p><span style="font-size:14px;"><span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法表集合</strong>是指由若干個<strong><span style="font-family:'Comic Sans MS';"><span style="font-family:'Microsoft YaHei';">方法表</span>(method_info)</span></strong>組成的集合。對於在類中定義的若干個,通過<span style="font-family:'Comic Sans MS';"><strong>JVM</strong></span>編譯成<strong><span style="font-family:'Comic Sans MS';">class</span></strong>文件後,會將相應的<span style="font-size:14px;"><span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;"><strong><span style="font-family:'Comic Sans MS';">method</span></strong></span></span></span>方法信息組織到一個叫作<strong>方法表集合</strong>的結構中,<strong>字段表集合</strong>是一個類數組結構,以下圖所示:</span></span></span></p> <blockquote> <p><img src="https://img-blog.csdn.net/20141114104145226" alt=""><br></p> </blockquote> <h3><a name="t2"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">2. method方法的描述-方法表集合在class文件中的位置</span></h3> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Comic Sans MS';">method</span></strong>方法的描述-<strong>方法表集合</strong>緊跟在<strong>字段表集合</strong>的後面(想了解<strong>字段表集合</strong>的讀者能夠<a href="http://blog.csdn.net/luanlouis/article/details/41046443" rel="nofollow" data-token="aff2d62ea4e1c9da373263a4d3b46e65">點擊我查看</a>),以下圖所示:</span></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="https://img-blog.csdn.net/20141114104728083" alt=""><br></p> <p><br></p> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">接下來讓咱們看看<strong><span style="font-family:'Comic Sans MS';">Method_info</span></strong> 結構體是怎麼組織<strong><span style="font-family:'Comic Sans MS';">method</span></strong>方法信息的:</span></p> </blockquote> <h3><a name="t3"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">3. 一個類中的method方法應該包含哪些信息?----method_info結構體的定義</span></h3> <p>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-family:'Microsoft YaHei';font-size:12px;">對於一個方法的表示,咱們根據咱們能夠歸納的信息以下所示:</span><br></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="https://img-blog.csdn.net/20141114150716551" alt=""><br></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 實際上<span style="font-family:'Comic Sans MS';"><strong>JVM</strong></span>還會對<strong><span style="font-family:'Comic Sans MS';">method</span></strong>方法的描述添加其餘信息,咱們將在後面詳細討論。</span><span style="font-family:'Microsoft YaHei';font-size:12px;">如上圖中的<strong><span style="font-family:'Comic Sans MS';">method_info結</span>構體</strong>的定義,該結構體的定義跟描述<strong><span style="font-family:'Comic Sans MS';">field</span>字段</strong> 的<strong><span style="font-family:'Comic Sans MS';">field_info</span>結構體</strong>的結構幾乎徹底一致,以下圖所示</span>。<br></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="https://img-blog.csdn.net/20141114144708625" alt=""><br></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp; 方法表的結構體由:<span style="color:#FF0000;"><strong>訪問標誌(<span style="font-family:'Comic Sans MS';">access_flags</span>)、名稱索引(<span style="font-family:'Comic Sans MS';">name_index</span>)、描述索引(<span style="font-family:'Comic Sans MS';">descriptor_index</span>)、屬性表(<span style="font-family:'Comic Sans MS';">attribute_info</span>)集合</strong></span>組成。</span></p> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>訪問標誌(<span style="font-family:'Comic Sans MS';">access_flags</span>):</strong></span></p> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Comic Sans MS';">method_info</span>結構體</strong>最前面的<strong>兩個字節</strong>表示的<strong>訪問標誌(access_flags)</strong>,記錄這這個方法的做用域、靜態or非靜態、可變性、是否可同步、是否本地方法、是否抽象等信息,實際上不止這些信息,咱們後面會詳細介紹訪問標誌這兩個字節的每一位具體表示什麼意思。</span></p> </blockquote> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><strong>名稱索引(<span style="font-family:'Comic Sans MS';">name_index</span>):</strong><br></span></span></p> <blockquote> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">緊跟在訪問標誌(access_flags)後面的<strong>兩個字節</strong>稱爲<strong>名稱索引</strong>,這兩個字節中的值指向了常量池中的某一個常量池項,這個方法的名稱以UTF-8格式的字符串存儲在這個<strong>常量池項</strong>中。如<span><span style="font-family:'Comic Sans MS';">public void methodName()</span></span>,很顯然,「<span style="font-family:'Comic Sans MS';"><span>methodName</span></span>」則表示着這個方法的名稱,那麼在常量池中會有一個<span style="font-family:'Comic Sans MS';">CONSTANT_Utf8_info</span>格式的常量池項,裏面存儲着<span style="font-family:'Microsoft YaHei';">「<span style="font-family:'Comic Sans MS';"><span>methodName</span></span>」</span>字符串,而<span style="font-family:'Comic Sans MS';">mehodName</span>()方法的方法表中的名稱索引則指向了這個常量池項。</span></span></p> </blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>描述索引(<span style="font-family:'Comic Sans MS';">descriptor_index</span>):</strong></span></p> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>描述索引表示的是這個方法的特徵或者說是簽名</strong>,<strong>一個方法會有若干個參數和返回值</strong>,而若干個參數的數據類型和返回值的數據類型構成了這個方法的描述,其基本格式爲:&nbsp;&nbsp;&nbsp;&nbsp;<strong> (參數數據類型描述列表)返回值數據類型&nbsp;</strong>&nbsp; 。咱們將在後面繼續討論。<br></span></p> </blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>屬性表(<span style="font-family:'Comic Sans MS';">attribute_info</span>)集合:</strong><br></span></p> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp; 這個屬性表集合很是重要,方法的實現被JVM編譯成JVM的<em><strong>機器碼指令</strong></em>,<span style="font-family:'Microsoft YaHei';"><em><strong>機器碼指令</strong></em></span>就存放在一個<strong><span style="font-family:'Comic Sans MS';">Code</span></strong>類型的屬性表中;若是方法聲明要拋出異常,那麼異常信息會在一個<strong><span style="font-family:'Comic Sans MS';">Exceptions</span></strong>類型的屬性表中予以展示。<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span>類型的屬性表能夠說是很是複雜的內容,也是本文最難的地方。</span></p> <p><br></p> </blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><em>接下來,咱們將一一擊破它們,看看它們究竟是怎麼表示的。</em><br></span></p> </blockquote> <h3><a name="t4"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">4. 訪問標誌(access_flags)---記錄着method方法的訪問信息</span></h3> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">訪問標誌(<strong><span style="font-family:'Comic Sans MS';color:#FF6600;">access_flags</span></strong>)共佔有<strong>2</strong> 個字節,分爲 <strong>16 </strong>位,這<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong> 16</strong></span>位 表示的含義以下所示:</span><br></p> <p><img src="https://img-blog.csdn.net/20141114161151578" alt=""></p> </blockquote> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">舉例:某個類中定義了以下方法:</span></p> <pre><code class="language-java hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">void</span> <span class="hljs-title">greeting</span><span class="hljs-params">()</span></span>{</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> }</div></div></li></ol></code><div class="hljs-button signin" data-title="登陸後複製" onclick="hljs.signin(event)"></div></pre><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">greeting()</span></strong>方法的修飾符有:<span style="color:#000099;"><span><span style="font-family:'Comic Sans MS';">public、static、synchronized、final</span></span></span> 這幾個修飾符修飾,那麼相對應地,<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">greeting()</span></strong></span>方法的訪問標誌中的<span style="font-family:'Comic Sans MS';color:#FF0000;">ACC_PUBLIC、ACC_STATIC、ACC_SYNCHRONIZED、ACC_FINAL</span>標誌位都應該是<strong>1</strong>,即:</span></span> <p><img src="https://img-blog.csdn.net/20141114170949140" alt=""><br></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">從上圖中能夠看出<strong>訪問標誌</strong>的值應該是二進制<strong>00000000 00111001,即十六進制0x0039</strong>。咱們將在文章的最後一個例子中證明這裏點。</span></p> </blockquote> <h3><a name="t5"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">5. 名稱索引和描述符索引----一個方法的簽名</span></h3> <blockquote> <p><span style="font-size:12px;">&nbsp;<span style="font-family:'Microsoft YaHei';">&nbsp;&nbsp; 緊接着<strong>訪問標誌(<span style="font-family:'Comic Sans MS';">access_flags</span>)</strong>後面的<strong>兩個字節</strong>,叫作<strong>名稱索引</strong>(<strong><span style="font-family:'Comic Sans MS';">name_index</span></strong>),這兩個字節中的值是指向了常量池中某個常量池項的索引,該常量池項表示這這個方法名稱的字符串。</span></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp; <strong>方法描述符索引(<span style="font-family:'Comic Sans MS';">descrptor_index</span>)</strong>是緊跟在<strong>名稱索引</strong>後面的兩個字節,這兩個字節中的值跟名稱索引中的值性質同樣,都是指向了常量池中的某個常量池項。這兩個字節中的指向的常量池項,<strong>是表示了方法描述符的字符串</strong>。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp; <u><span style="color:#FF0000;"><strong>所謂的方法描述符,實質上就是指用一個什麼樣的字符串來描述一個方法,</strong></span></u>方法描述符的組成以下圖所示:</span></p> </blockquote> <blockquote> <p><img src="https://img-blog.csdn.net/20141114180514489" alt=""><br></p> </blockquote> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size:12px;">&nbsp;<span style="font-family:'Microsoft YaHei';">&nbsp; 關於不一樣的<strong>數據類型的描述符</strong>是怎樣的,我已經在<a name="41046443" href="http://blog.csdn.net/luanlouis/article/details/41046443" rel="nofollow" data-token="aff2d62ea4e1c9da373263a4d3b46e65">《Java虛擬機原理圖解》1.4 class文件中的字段表集合--field字段在class文件中是怎樣組織的</a>&nbsp; 第五部分字段的數據類型表示和字段名稱表示 進行過詳細的闡釋,感興趣的讀者能夠前去查看。</span></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 舉例:對於以下定義的的<strong><span style="font-family:'Comic Sans MS';">greeting()</span></strong>方法,咱們來看一下對應的<strong><span style="font-family:'Comic Sans MS';">method_info</span></strong>結構體中的名稱索引和描述符索引信息是怎樣組織的。</span></p> <p></p> <pre><code class="language-java hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">void</span> <span class="hljs-title">greeting</span><span class="hljs-params">()</span></span>{</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> }</div></div></li></ol></code><div class="hljs-button signin" data-title="登陸後複製" onclick="hljs.signin(event)"></div></pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size:12px;"> <span style="font-size:12px;"> <span style="font-family:'Microsoft YaHei';">以下圖所示,<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">method_info</span></strong></span>結構體的名稱索引中存儲了一個索引值<strong>x</strong>,指向了常量池中的第<strong>x</strong>項,第<strong> x</strong>項表示的是字符串"<span style="color:#FF0000;"><strong><span style="font-family:'Comic Sans MS';">greeting</span></strong></span>",即表示該方法名稱是"<span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><span style="color:#FF0000;"><strong><span style="font-family:'Comic Sans MS';">greeting</span></strong></span></span></span>";描述符索引中的<strong><span style="font-family:'Comic Sans MS';">y</span></strong> 值指向了常量池的第<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">y</span></strong></span>項,該項表示字符串"<strong><span style="color:#FF0000;">()V</span></strong>",即表示該方法沒有參數,返回值是<strong>void</strong>類型。</span></span></span> <p></p> <blockquote> <p><img src="https://img-blog.csdn.net/20141115094626151" alt=""><br></p> </blockquote> <p><br></p> <h3><a name="t6"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">6.屬性表集合--記錄方法的機器指令和拋出異常等信息</span><br></h3> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size:12px;"> <span style="font-family:'Microsoft YaHei';"> 屬性表集合記錄了某個方法的一些屬性信息,這些信息包括:</span></span></p> <blockquote> <ul><li><span style="font-family:'Microsoft YaHei';font-size:12px;">這個方法的代碼實現,<span style="color:#FF0000;">即<strong>方法的可執行的機器指令</strong></span></span></li><li><span style="font-family:'Microsoft YaHei';font-size:12px;">這個方法聲明的<strong>要拋出的異常信息</strong></span></li><li><span style="font-family:'Microsoft YaHei';font-size:12px;">這個方法是否<strong>被@deprecated註解表示</strong></span></li><li><span style="font-family:'Microsoft YaHei';font-size:12px;">這個方法是不是<strong>編譯器自動生成的</strong></span></li></ul></blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>屬性表(attribute_info)</strong>結構體的通常結構以下所示:</span></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="https://img-blog.csdn.net/20141115145825045" alt=""></p> <h4><span style="font-family:'Microsoft YaHei';font-size:14px;">6.1 Code類型的屬性表--method方法中的機器指令的信息</span></h4> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp; <strong>Code</strong>類型的<strong>屬性表(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_info</span>)</strong>能夠說是<span style="color:#FF6600;"><strong>class</strong></span>文件中最爲重要的部分,由於它包含的是<strong>JVM</strong>能夠運行的機器碼指令,<strong>JVM</strong>可以運行這個類,就是從這個屬性中取出機器碼的。除了要執行的機器碼,它還包含了一些其餘信息,以下所示:</span></p> <p><img src="https://img-blog.csdn.net/20141116114625218" alt=""></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>Code屬性表</strong>的組成部分:</span></p> <p><span style="font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';">機器指令----code:</span></strong></span></p> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">目前的<strong><span style="font-family:'Comic Sans MS';">JVM</span></strong>使用一個字節表示機器操做碼,即對<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">JVM</span></strong></span>底層而言,它能表示的機器操做碼很少於<strong>2</strong>的 <strong>8</strong> 次方,即 <strong>256</strong>個。<strong><span style="font-family:'Comic Sans MS';">class</span></strong>文件中的機器指令部分是<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">class</span></strong></span>文件中最重要的部分,而且很是複雜,本文的重點不止介紹它,我將專門在一片博文中討論它,敬請期待。</span></p> </blockquote> <p><span style="font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';">異常處理跳轉信息---exception_table:</span></strong></span></p> <blockquote> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;">若是代碼中出現了<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">try{}catch{}</span></strong></span>塊,那麼<span style="font-family:'Microsoft YaHei';"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">try{}</span></strong></span></span>塊內的機器指令的地址範圍記錄下來,而且記錄對應的<span style="font-family:'Microsoft YaHei';"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">catch{}</span></strong></span></span>塊中的起始機器指令地址,當運行時在<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">try</span></strong></span>塊中有異常拋出的話,<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">JVM</span></strong></span>會將<span style="font-family:'Microsoft YaHei';"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">catch{}</span></strong></span></span>塊對應懂得其實機器指令地址傳遞給<strong>PC寄存器</strong>,從而實現指令跳轉;</span></span></p> </blockquote> <p><span style="font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';">Java源碼行號和機器指令的對應關係---LineNumberTable屬性表:</span></strong></span></p> <blockquote> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>編譯器在將<span style="font-family:'Comic Sans MS';">java</span>源碼編譯成<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">class</span></span>文件時,會將源碼中的語句行號跟編譯好的機器指令關聯起來,這樣的<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">class</span></span>文件加載到內存中並運行時,若是拋出異常,<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">JVM</span></span>能夠根據這個對應關係,拋出異常信息,告訴咱們咱們的源碼的多少行有問題,方便咱們定位問題。</strong>這個信息不是運行時必不可少的信息,可是默認狀況下,編譯器會生成這一項信息,若是你項取消這一信息,你可使用<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">-g:none</span></strong></span> 或<strong><span style="font-family:'Comic Sans MS';color:#FF6600;">-g:lines</span></strong>來取消或者要求設置這一項信息。若是使用了<span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';color:#FF6600;">-g:none</span></strong></span>來生成class文件,<strong><span style="color:#FF0000;"><u>class文件中將不會有LineNumberTable屬性表,形成的影響就是 未來若是代碼報錯,將沒法定位錯誤信息</u>報錯的行,而且若是項調試代碼,將不能在此類中打斷點(由於沒有指定行號。)</span></strong></span></span></p> </blockquote> <p><span style="font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';">局部變量表描述信息----LocalVariableTable屬性表:</span></strong></span></p> <blockquote> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;">局部變量表信息會記錄棧幀局部變量表中的變量和<span style="font-family:'Microsoft YaHei';"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">java</span></strong></span></span>源碼中定義的變量之間的關係,這個信息不是運行時必須的屬性,默認狀況下不會生成到<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Microsoft YaHei';"><strong><span style="font-family:'Comic Sans MS';">class</span></strong></span></span>文件中。你能夠根據<strong><span style="font-family:'Comic Sans MS';color:#FF6600;">javac</span></strong>指令的<span style="font-family:'Microsoft YaHei';"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">-g:none</span></strong></span></span>或者<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>-g:vars</strong></span>選項來取消或者設置這一項信息。</span></span></p> <p><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><span style="color:#FF0000;"><strong>它有什麼做用呢?</strong></span>&nbsp; 當咱們使用IDE進行開發時,最喜歡的莫過於它們的代碼提示功能了。若是在項目中引用到了第三方的jar包,而第三方的包中的class文件中有無<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>LocalVariableTable</strong></span>屬性表的區別以下所示:</span></span></span></p> <p><img src="https://img-blog.csdn.net/20141116221304421" alt=""></p> </blockquote> <fieldset><legend><span style="font-family:'Microsoft YaHei';font-size:12px;">Code屬性表結構體的解釋:</span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">1.<span style="font-family:'Comic Sans MS';"><strong><span style="color:#FF9900;"><span style="color:#FF6600;">attribute_name_index</span></span></strong></span><strong>,屬性名稱索引</strong>,佔有<strong>2</strong>個字節,其內的值指向了常量池中的某一項,該項表示字符串「<span style="color:#3333FF;"><span><span style="font-family:'Comic Sans MS';"><strong>Code</strong></span></span></span>」;<br> 2. <span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">attribute_length</span></strong></span><strong>,屬性長度</strong>,佔有<strong> 4</strong>個字節,其內的值表示後面有多少個字節是屬於此Code屬性表的;<br> 3. <span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">max_stack,</span></strong></span><strong>操做數棧深度的最大值</strong>,佔有<strong> 2</strong> 個字節,在方法執行的任意時刻,操做數棧都不該該超過這個值,虛擬機的運行的時候,會根據這個值來設置該方法對應的<strong>棧幀(Stack Frame)</strong>中的操做數棧的深度;<br> 4. <span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>max_locals</strong></span>,<strong>最大局部變量數目,</strong>佔有<strong> 2</strong>個字節,其內的值表示局部變量表所須要的存儲空間大小;<br> 5. <strong><span style="font-family:'Comic Sans MS';color:#FF6600;">code_length</span></strong>,<strong>機器指令長度</strong>,佔有<strong> 4</strong> 個字節,表示跟在其後的多少個字節表示的是機器指令;<br> 6. <span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>code,</strong></span><strong>機器指令區域</strong>,該區域佔有的字節數目由&nbsp;<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Comic Sans MS';color:#FF6600;">code_length</span></strong></span>中的值決定。JVM最底層的要執行的機器指令就存儲在這裏;<br> 7.<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';"> exception_table_length</span></strong></span>,<strong>顯式異常表長度</strong>,佔有<strong>2</strong>個字節,若是在方法代碼中出現了<span style="font-family:'Comic Sans MS';color:#FF6600;">try{} catch()</span>形式的結構,該值不會爲空,緊跟其後會跟着若干個<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">exception_table</span></strong></span>結構體,以表示異常捕獲狀況;<br> 8. <span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">exception_table</span></strong></span>,<strong>顯式異常表</strong>,佔有<strong>8</strong> 個字節,<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">start_pc,end_pc,handler_pc</span></strong></span>中的值都表示的是<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">PC</span></strong></span>計數器中的指令地址。<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">exception_table</span></strong></span></span>表示的意思是:若是字節碼從第<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">start_pc</span></strong></span></span></span></strong></span></span>行到第<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">end_pc</span></strong></span></span>行之間出現了<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">catch_type</span></strong></span>所描述的異常類型,那麼將跳轉到<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">handler_pc</span></strong></span></span>行繼續處理。<br> 9.<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';"> attribute_count,</span></strong></span><strong>屬性計數器</strong>,佔有<strong> 2</strong> 個字節,表示<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span>屬性表的其餘屬性的數目<br> 10. <span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">attribute_info</span></strong></span>,表示<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span></span><strong>屬性表</strong>具備的屬性表,它主要分爲兩個類型的屬性表:「<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">LineNumberTable</span></strong></span>」類型和「<span style="font-family:'Comic Sans MS';"><strong><span style="color:#FF6600;">LocalVariableTable</span></strong></span>」類型。<br> 「<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">LineNumberTable</span></strong></span></span>」類型的屬性表記錄着<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Java</span></strong></span>源碼和機器指令之間的對應關係<br> 「<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';"><strong><span style="color:#FF6600;">LocalVariableTable</span></strong></span></span>」類型的屬性表記錄着局部變量描述</span></p> </fieldset><p><em><strong><span style="font-family:'Microsoft YaHei';font-size:14px;">舉例:</span></strong></em></p> <p><span style="font-family:'Microsoft YaHei';">&nbsp;&nbsp;&nbsp;<span style="font-size:12px;"> <em> 以下定義Simple類,使用javac -g:none Simple.java 編譯出Simple.class 文件,並使用javap -v Simple &gt; Simple.txt 查看反編譯的信息,而後看Simple.class文件中的方法表集合是怎樣組織的:</em></span></span></p> <pre><code class="language-java hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">package</span> com.louis.jvm;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Simple</span> </span>{</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">void</span> <span class="hljs-title">greeting</span><span class="hljs-params">()</span></span>{</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">int</span> a = <span class="hljs-number">10</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> }</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">}</div></div></li></ol></code><div class="hljs-button signin" data-title="登陸後複製" onclick="hljs.signin(event)"></div></pre> <p><em><strong><span style="font-family:'Microsoft YaHei';font-size:14px;">1. Simple.class文件組織信息以下所示:</span></strong></em></p> <p><img src="https://img-blog.csdn.net/20141117100511124" alt=""><br></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">如上所示,方法表集合使用了藍色線段圈了起來。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">請注意:方法表集合的頭兩個字節,即<strong>方法表計數器(<span style="font-family:'Comic Sans MS';color:#FF6600;">method_count</span>)</strong>的值是<strong>0x0002</strong>,它表示該類中有<strong>2 </strong>個方法。細心的讀者會注意到,咱們的<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>Simple.java</strong></span>中就定義了一個<span style="font-family:'Comic Sans MS';color:#FF6600;">greeting()</span>方法,爲何<strong>class</strong>文件中會顯示有兩個方法呢??</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">在<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>Simple.classz中</strong></span></span>出現了兩個方法表,分別表明構造方法<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>&lt;init&gt;()</strong></span>和<strong> <span style="font-family:'Comic Sans MS';color:#FF6600;">greeting()</span></strong>方法,如今讓咱們分別來討論這兩個方法:</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><br></span></p> <p><em><strong><span style="font-family:'Microsoft YaHei';font-size:14px;">2.&nbsp; Simple.class 中的&lt;init&gt;() 方法:</span></strong></em></p> <p><img src="https://img-blog.csdn.net/20141117111623566" alt=""><br></p> <p><span style="font-family:SimHei;"><strong><span style="font-size:14px;">&nbsp;解釋:</span></strong></span></p> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;1.<strong> 方法訪問標誌(<span style="font-family:'Comic Sans MS';color:#FF6600;">access_flags</span>)</strong>: 佔有<span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span></strong></span>個字節,值爲<strong>0x0001</strong>,即標誌位的第 <strong>16</strong> 位爲<strong> 1</strong>,因此該<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">&lt;init&gt;()</span></strong></span>方法的修飾符是:<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">ACC_PUBLIC</span></strong></span>;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;2.<strong> 名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">name_index</span>)</strong>: 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span> </strong></span></span>個字節,值爲<strong> 0x0004</strong>,指向常量池的第<strong> 4</strong>項,該項表示字符串「<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">&lt;init&gt;</span></strong></span></span>」,即該方法的名稱是「<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">&lt;init&gt;</span></strong></span></span>」;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;3<strong>.描述符索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">descriptor_index</span>)</strong>: 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span> </strong></span></span></span>個字節,值爲<strong>0x0005</strong>,指向常量池的第 <strong> 5</strong> 項,該項表示字符串「<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">()V</span></strong></span>」,即表示該方法不帶參數,而且無返回值(構造函數確實也沒有返回值);</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">4. <strong>屬性計數器(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_count</span>):</strong> 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span> </strong></span></span></span></span>個字節,值爲<strong>0x0001</strong>,表示該方法表中含有一個屬性表,後面會緊跟着一個屬性表;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">5.<strong> 屬性表的名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_name_index</span>)</strong>:佔有<strong> 2</strong> 個字節,值爲<strong>0x0006</strong>,指向常量池中的第<strong>6</strong> 項,該項表示字符串「<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span>」,表示這個屬性表是<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span></span>類型的屬性表;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">6. <strong>屬性長度(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_length</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">4</span></strong></span></span></span></span>個字節,值爲<strong>0x0000 0011</strong>,即十進制的 <strong>17</strong>,代表後續的<strong> 17</strong> 個字節能夠表示這個<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span></span>屬性表的屬性信息;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">7. <strong>操做數棧的最大深度(<span style="font-family:'Comic Sans MS';color:#FF6600;">max_stack</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">2</span></strong></span></span></span></span>個字節,值爲<strong>0x0001</strong>,表示棧幀中操做數棧的最大深度是<strong>1</strong>;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">8. <strong>局部變量表的最大容量(<span style="font-family:'Comic Sans MS';color:#FF6600;">max_variable</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">2</span></strong></span></span></span></span>個字節,值爲<strong>0x0001</strong>, <span style="font-family:'Comic Sans MS';"><strong>JVM</strong></span>在調用該方法時,根據這個值設置棧幀中的局部變量表的大小;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">9. <strong>機器指令數目(<span style="font-family:'Comic Sans MS';color:#FF6600;">code_length</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">4</span></strong></span></span></span></span></span>個字節,值爲<strong>0x0000 0005</strong>,表示後續的<strong>5 </strong>個字節<strong> <span style="color:#3333FF;">0x2A 、0xB七、 0x00、0x0一、0xB1</span></strong>表示機器指令;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">10. <strong>機器指令集<span style="font-family:'Comic Sans MS';">(<span style="color:#FF6600;">code[code_length]</span></span>)</strong>:這裏共有<span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong>&nbsp;<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">5</span></strong></span></span></span></span></span></strong></span></span></span></span></span>個字節,值爲<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="color:#3333FF;">0x2A 、0xB七、 0x00、0x0一、0xB1</span></strong></span></strong></span>;</span></p> </blockquote> <blockquote></blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">11.<strong> 顯式異常表集合(<span style="font-family:'Comic Sans MS';color:#FF6600;">exception_table_count</span>)</strong>: 佔有<strong>2</strong> 個字節,值爲<strong>0x0000</strong>,表示方法中沒有須要處理的異常信息;</span></p> <p><span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;">12. <strong> Code屬性表的屬性表集合(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_count</span>)</strong>: 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>2</strong> </span>個字節,值爲<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>0x0000</strong></span>,表示它沒有其餘的屬性表集合,由於咱們使用了<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">-g:none</span></strong></span> 禁止編譯器生成<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span><strong>屬性表</strong>的<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';"> LineNumberTable 和LocalVariableTable</span></strong></span>;</span><br></span></p> <p><span style="font-family:'Microsoft YaHei';"><br></span></p> <p><em><strong><span style="font-family:'Microsoft YaHei';font-size:14px;">B.&nbsp; Simple.class 中的greeting() 方法:</span></strong></em></p> <p><img src="https://img-blog.csdn.net/20141117123854641" alt=""><br></p> <p></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;解釋:</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;1. <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>方法訪問標誌(<span style="font-family:'Comic Sans MS';color:#FF6600;">access_flags</span>)</strong></span>: 佔有<strong> 2</strong>個字節,值爲 <strong>0x0039</strong> ,即二進制的<strong>00000000 00111001</strong>,即標誌位的第<strong>十一、十二、1三、16</strong>位爲<strong>1</strong>,根據上面講的方法標誌位的表示,能夠獲得該<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>greeting()</strong></span>方法的修飾符有:<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>ACC_SYNCHRONIZED、ACC_FINAL、ACC_STATIC、ACC_PUBLIC</strong></span>;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;2.<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong> 名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">name_index</span>)</strong>: 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span> </strong></span></span>個字節</span>,值爲<strong> 0x0007</strong>,指向常量池的第<strong> 7</strong> 項,該項表示字符串「<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>greeting</strong></span></span>」,即該方法的名稱是「<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>greeting</strong></span></span>」;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;3. <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>描述符索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">descriptor_index</span>)</strong>: 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span> </strong></span></span></span>個字節,</span>值爲<strong>0x0005</strong>,指向常量池的第<strong> 5</strong> 項,該項表示字符串「<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>()V</strong></span>」,即表示該方法不帶參數,而且無返回值;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">4. <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>屬性計數器(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_count</span>):</strong> 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span> </strong></span></span></span></span>個字節,</span>值爲<strong>0x0001</strong>,表示該方法表中含有一個屬性表,後面會緊跟着一個屬性表;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">5.<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>屬性表的名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_name_index</span>)</strong>:</span><span style="font-family:'Microsoft YaHei';font-size:12px;"></span><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;">佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;"> 2</span> </strong></span></span></span></span>個字節,</span></span>值爲<strong>0x0006</strong>,指向常量池中的第<strong>6 </strong>項,該項表示字符串「<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span>」,表示這個屬性表是<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span></span>類型的屬性表;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">6. <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>屬性長度(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_length</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">4</span></strong></span></span></span></span>個字節,</span>值爲<strong>0x0000 0010</strong>,即十進制的<strong>16</strong>,代表後續的<strong>16</strong>個字節能夠表示這個<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span></span>屬性表的屬性信息;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">7. <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>操做數棧的最大深度(<span style="font-family:'Comic Sans MS';color:#FF6600;">max_stack</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">2</span></strong></span></span></span></span>個字節,</span>值爲<strong>0x0001</strong>,表示棧幀中操做數棧的最大深度是<strong>1</strong>;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">8. <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>局部變量表的最大容量(<span style="font-family:'Comic Sans MS';color:#FF6600;">max_variable</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"><strong><span style="color:#000000;">2</span></strong></span></span></span></span>個字節</span>,值爲<strong>0x0001</strong>, <strong>JVM</strong>在調用該方法時,根據這個值設置棧幀中的局部變量表的大小;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">9. <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>機器指令數目(<span style="font-family:'Comic Sans MS';color:#FF6600;">code_length</span>)</strong>:</span>佔有<strong>4 </strong>個字節,值爲<strong>0x0000 0004,</strong>表示後續的<strong>4</strong>個字節<strong><span><span style="color:#000099;"><span style="color:#3333FF;"><span>0x十、 0x0A、 0x3B、0xB1</span></span></span></span></strong>的是表示機器指令;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">10.<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>機器指令集(code[code_length])</strong></span>:這裏共有<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>4 </strong></span>個字節,值爲<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span><span style="color:#000099;"><span style="color:#3333FF;"><span>0x十、 0x0A、 0x3B、0xB1</span></span></span></span></strong></span>&nbsp;;</span></p> <blockquote></blockquote> <p></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">11.<strong> 顯式異常表集合(<span style="font-family:'Comic Sans MS';color:#FF6600;">exception_table_count</span>)</strong>: 佔有<strong>2</strong> 個字節,值爲<strong>0x0000</strong>,表示方法中沒有須要處理的異常信息;</span></p> <span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;">12. <strong> Code屬性表的屬性表集合(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_count</span>)</strong>: 佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>2</strong> </span>個字節,值爲<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>0x0000</strong></span>,表示它沒有其餘的屬性表集合,由於咱們使用了<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">-g:none</span></strong></span> 禁止編譯器生成<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';">Code</span></strong></span><strong>屬性表</strong>的<span style="color:#FF6600;"><strong><span style="font-family:'Comic Sans MS';"> LineNumberTable 和LocalVariableTable</span></strong></span>;</span></span> <p><br></p> <p><br></p> </blockquote> <h4><span style="font-family:'Microsoft YaHei';font-size:14px;">6.2 Exceptions類型的屬性表----method方法聲明的要拋出的異常信息</span></h4> <blockquote> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">有些方法在定義的時候,會聲明該方法會拋出什麼類型的異常,以下定義一個<span style="color:#FF0000;"><strong><span style="font-family:'Comic Sans MS';">Interface</span></strong></span>接口,它聲明瞭<span style="font-family:'Comic Sans MS';color:#FF6600;">sayHello()</span>方法,拋出<span style="font-family:'Comic Sans MS';color:#FF6600;">Exception</span>異常:</span></p> <pre><code class="language-java hljs"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">package</span> com.louis.jvm;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Interface</span> </span>{</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">}</div></div></li></ol></code><div class="hljs-button signin" data-title="登陸後複製" onclick="hljs.signin(event)"></div></pre> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">如今讓咱們看一下<strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';">Exception</span></span>s</strong>類型的<strong>屬性表(attribute_info)</strong>結構體是怎樣組織的:</span><br></p> <p><img src="https://img-blog.csdn.net/20141115154139486" alt=""></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">如上圖所示,<strong><span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">Exception</span></span>s</strong></span><span style="font-family:'Microsoft YaHei';">類型的<strong>屬性表(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_info</span>)</strong>結構體由一下元素組成:</span></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>屬性名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_name_index</span>)</strong>:佔有<strong> 2</strong>個字節,其中的值指向了常量池中的表示"<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';">Exception</span></span>s</strong></span>"字符串的常量池項;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>屬性長度(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_length</span>)</strong>:它比較特殊,佔有<strong>4</strong>個字節,它的值表示跟在其後面多少個字節表示異常信息;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>異常數量(<span style="font-family:'Comic Sans MS';color:#FF6600;">number_of_exceptions</span>)</strong>:佔有<strong>2</strong> 個字節,它的值表示方法聲明拋出了多少個異常,即表示跟在其後有多少個<strong>異常名稱索引</strong>;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>異常名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">exceptions_index_table</span>)</strong>:佔有<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>2</strong></span>個字節,它的值指向了常量池中的某一項,該項是一個<span style="font-family:'Comic Sans MS';color:#FF6600;">CONSTANT_Class_info</span>類型的項,表示這個異常的徹底限定名稱;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><br></span></p> <fieldset><legend><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';">Exception</span></span>s</strong></span>類型的<strong>屬性表</strong>的長度計算</span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">若是某個方法定義中,沒有聲明拋出異常,那麼,表示該方法的<strong>方法表(<span style="font-family:'Comic Sans MS';color:#FF6600;">method_info</span>)</strong>結構體中的屬性表集合中不會有Exceptions類型的屬性表;換句話說,若是方法聲明瞭要拋出的異常,<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>方法表(<span style="font-family:'Comic Sans MS';color:#FF6600;">method_info</span>)</strong></span>結構體中的屬性表集合中必然會有<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';">Exception</span></span>s</strong></span></span>類型的屬性表,而且該屬性表中的異常數量<span style="color:#FF0000;">不小於1</span>。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">咱們假設異常數量中的值爲<span style="color:#FF0000;"> N</span>,那麼後面的異常名稱索引的數量就爲<span style="color:#FF0000;">N</span>,它們總共佔有的字節數爲<span style="color:#FF0000;"><strong>N*2</strong></span>,而異常數量佔有<span style="color:#FF0000;"><strong>2</strong></span>個字節,那麼將有下面的這個關係式:</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family:'Microsoft YaHei';font-size:12px;"> <strong>屬性長度(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_length</span>)</strong></span>中的值=&nbsp;<strong>2&nbsp; + 2*</strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>異常數量(<span style="font-family:'Comic Sans MS';color:#FF6600;">number_of_exceptions</span>)</strong></span>中的值</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family:'Microsoft YaHei';font-size:12px;"> <span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';">Exception</span></span>s</strong></span></span>類型的<strong>屬性表(<span style="font-family:'Comic Sans MS';color:#FF0000;">attribute_info</span>)</strong>的長度=<strong>2+4+</strong><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>屬性長度(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_length</span>)</strong></span>中的值<br></span></p> </fieldset><p><span style="font-family:'Microsoft YaHei';font-size:12px;">舉例:</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">將上面定義的<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF0000;"><strong><span style="font-family:'Comic Sans MS';">Interface</span></strong></span></span>接口類編譯成<strong><span style="font-family:'Comic Sans MS';">class</span></strong>文件,而後咱們查看<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Comic Sans MS';">Interface</span></strong></span></span>.<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong><span style="font-family:'Comic Sans MS';">class</span></strong></span>文件,找出方法表集合所在位置和相應的數據,並輔助<span style="font-family:'Comic Sans MS';"><strong><span>javap -v&nbsp; Inerface </span></strong></span>查看常量池信息,以下圖所示:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><img src="https://img-blog.csdn.net/20141115114030609" alt=""></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因爲<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">sayHello()</span></span>方法是在的<strong><span style="font-family:'Comic Sans MS';">Interface</span></strong>接口類中聲明的,它沒有被實現,因此它對應的<strong>方法表(<span style="font-family:'Comic Sans MS';color:#FF6600;">method_info</span>)</strong>結構體中的<strong>屬性表集合</strong>中<span style="color:#FF0000;">沒有</span><strong>Code類型的屬性表</strong>。<br></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">注:</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">1. <strong>方法計數器(<span style="font-family:'Comic Sans MS';color:#FF6600;">methods_count</span>)</strong>中的值爲<strong>0x0001</strong>,代表其後的<strong>方法表<span style="font-family:'Comic Sans MS';color:#FF6600;">(method_info</span>)</strong>就一個,即咱們就定義了一個方法,其後會緊跟着一個<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong>方法表<span style="font-family:'Comic Sans MS';color:#FF6600;">(method_info</span>)</strong></span>結構體;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">2. <strong>方法的訪問標誌(<span style="font-family:'Comic Sans MS';color:#FF6600;">access_flags</span>)</strong>的值是<strong>0x0401</strong>,二進制是<strong>00000100 00000001</strong>,第<strong>6</strong>位和第<strong>16</strong>位是<strong>1</strong>,對應上面的標誌位信息,能夠得出它的<strong>訪問標誌符</strong>有:<span style="font-family:'Comic Sans MS';color:#FF6600;"><strong>ACC_ABSTRACT、ACC_PUBLIC</strong></span>。細心的讀者可能會發現,在上面聲明的<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">sayHello()</span></span></span>方法中並無聲明爲<span style="font-family:'Comic Sans MS';color:#FF6600;">abstract</span>類型啊。確實如此,這是由於<strong><span style="color:#FF0000;">編譯器對於接口內聲明的方法自動加上ACC_ABSTRACT標誌</span></strong>。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">3. <strong>名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">name_index</span>)</strong>中的值爲<strong>0x0005</strong>,<strong>0x0005</strong>指向了常量池的第<strong>5</strong>項,第五項表示的字符串爲「<span style="font-family:'Comic Sans MS';"><strong><span style="color:#000099;">sayHello</span></strong></span>」,即表示的方法名稱是<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';"><strong><span style="color:#000099;">sayHello</span></strong></span></span></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">4. <strong>描述符索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">descriptor_index</span>)</strong>中的值爲<strong>0x0006</strong>,<strong>0x0006</strong>指向了常量池中的第<strong>6</strong>項,第<strong>6</strong>項表示的字符串爲「<strong>()V</strong>」 表示這個方法的無入參,返回值爲<strong><span style="font-family:'Comic Sans MS';">void</span></strong>類型</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">5. <strong>屬性表計數器(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_count</span>)</strong>中的值爲<strong>0x0001</strong>,表示後面的<strong>屬性表</strong>的個數就<strong>1</strong>個,後面緊跟着一個<span style="font-family:'Comic Sans MS';"><strong><span style="color:#FF6600;">attribute_info</span></strong></span>結構體;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">6. <strong>屬性表(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_info</span>)</strong>中的<strong>屬性名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_name_index</span>)</strong>中的值爲<strong>0x0007</strong>,<strong>0x0007</strong>指向了常量池中的第<strong>7</strong> 項,第<span style="font-family:'Microsoft YaHei';font-size:12px;"><strong> 7</strong></span>項指向字符串「<span style="font-family:'Comic Sans MS';"><strong><span style="color:#FF6600;">Exceptions</span></strong></span>」,即表示該屬性表表示的異常信息;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">7. <strong>屬性長度(<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_length</span>)</strong>中的值爲:<strong>0x00000004</strong>,即後續的<strong>4</strong>個字節將會被解析成屬性值;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">8. <strong>異常數量(<span style="font-family:'Comic Sans MS';color:#FF6600;">number_of_exceptions</span>)</strong>中的值爲<strong>0x0001</strong>,表示這個方法聲明拋出的異常個數是<strong>1</strong>個;</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">9.<strong>異常名稱索引(<span style="font-family:'Comic Sans MS';color:#FF6600;">exception_index_table</span>)</strong>中的值爲<strong>0x0008</strong>,指向了常量池中的第<strong>8</strong>項,第<strong>8</strong>項表示的是<strong><span style="font-family:'Comic Sans MS';">CONSTANT_Class_info</span></strong>類型的常量池項,表示「<span style="font-family:'Comic Sans MS';"><strong><span style="color:#000099;">java/lang/Exception</span></strong></span>」,即表示此方法拋出了<span style="font-family:'Comic Sans MS';"><strong>java.lang.Exception</strong></span>異常。</span></p> <br></blockquote> <br><h3><a name="t7"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">7.&nbsp; IDE代碼提示功能實現的基本原理<br></span></h3> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family:'Microsoft YaHei';font-size:12px;">如今對於企業級的開發,開發者們愈來愈依賴IDE如Intellij IDEA、Eclipse、MyEclipse、NetBeans等,利用他們提供的高級功能,能夠極大地提升編碼的速度和效率。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每一個IDE都提供了代碼提示功能,它們實現的基本原理其實就是IDE針對它們項目下的包中全部的class文件進行建模,解析出它們的方法信息,當咱們必定的條件時,IDE會自動地將合適條件的方法列表展現給開發者,供開發者使用。</span></p> <blockquote> <p><img src="https://img-blog.csdn.net/20141117142215355" alt=""></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">在上面將Code屬性表的時候也講了,若是編譯的第三方包,沒有LocalVariableTable屬性表信息,IDE的提示信息會稍有不一樣:</span></p> <p><img src="https://img-blog.csdn.net/20141117142426801" alt=""></p> <p><br></p> <p><br></p> </blockquote> <p></p> <h3><a name="t8"></a><span style="font-family:'Microsoft YaHei';font-size:14px;">8.&nbsp; 寫在後面<br></span></h3> <p>&nbsp; &nbsp; <span style="font-family:'Microsoft YaHei';">&nbsp;&nbsp;<span style="font-size:12px;"> 以上就是Class文件的方法表集合的所有內容。</span></span></p> <p><span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 讀者可能以爲本文關於方法表的Code屬性表討論的不夠深刻,在討論Code屬性表的時候,我簡單介紹了它的兩個屬性表LineNumberTable 和LocalVariableTable這兩個在有什麼實際做用,可是沒有詳細第介紹它們,而且在列舉的例子中,刻意地使用了&nbsp; -g:none 選項 ,以使生成的class文件沒有這兩項信息,這麼作是由於Code 屬性太過複雜,而本文主要是想讓讀者瞭解的是 方法表集合,因此就生成了最精簡的Code屬性表,以減小讀者的負擔。</span></span></p> <p><span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;<strong><em><span style="color:#000099;">接下來的一篇文章,我打算專門來討論Code屬性表,揭開Code屬性表的全部祕密,敬請關注~~</span></em></strong><br></span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">&nbsp;&nbsp;&nbsp;&nbsp; 本文還引出了一個須要討論的話題:就是<span style="color:#000099;"><em><strong>Code屬性表中的機器指令</strong></em></span></span></span>,<span style="font-family:'Microsoft YaHei';font-size:12px;">機器指令的運行要依賴於JVM體系結構的設計機制,理解機器指令的運行機制,這將是根很是很是難啃的骨頭.......<br></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br></p> <p><br></p> <p><br></p> <blockquote> <p></p> <fieldset><legend>做者給讀者的一些建議:</legend> <p><span style="font-family:'Comic Sans MS';">1. 因爲class文件的信息繁雜,爲了減小class文件的複雜程度,本文列舉的例子都是針對特定狀況精簡的,儘可能減小沒必要要的學習障礙,因此做者但願讀者好好研究一下本文所列舉的例子,讀者最好本身動手,本身編譯源代碼,生成class文件,並查看class文件中的信息,而後逐字節分析,若是你真這麼作了,你會發現,class文件的組織格式原來真的很簡單..</span></p> <p><span style="font-family:'Comic Sans MS';">2. 閱讀了本文,並不能保證讓你徹底、系統地掌握class文件組織形式。若是你想全面系統地掌握它,你還須要閱讀:</span><br></p> <p>&nbsp;&nbsp;&nbsp;<em> <a href="http://download.csdn.net/detail/u010349169/7439669" rel="nofollow" data-token="b4592b628b95b59a3c3c9ba19ee1a97d"> 《Java Vritual Machine Specification _J2SE 7》(Java虛擬機規範 Java SE7 版)(可點擊下載)</a></em></p> <p>&nbsp;&nbsp;&nbsp;<em> 《<a href="http://download.csdn.net/detail/u010349169/8168053" rel="nofollow" data-token="da7ca14ca8a1ce88344c21b7af819f85">深刻理解Java虛擬機:JVM高級特性與最佳實踐》,周志明(可點擊下載)</a></em></p> <p>&nbsp;&nbsp;&nbsp; 這兩本書很系統地介紹了class文件的組織形式,若是你以爲這兩本書中有的部分將的太抽象,很差理解,那麼你再回頭看看本文,本文能給你一個形象化和直觀化的解釋。</p> <p><br></p> <p>衷心但願《Java虛擬機原理圖解》這個專欄可以幫助到廣大的Java 程序員們!</p> </fieldset><p></p> </blockquote> </div> 本文源自&nbsp; http://blog.csdn.net/luanlouis/java

相關文章
相關標籤/搜索