JVM系列(1)-變量

前言

這段時間一直在看JVM相關的書籍,雖然有點難,至少到目前爲止尚未放棄。寫這篇文章的目的:當作本身這段時間學習的小回顧。本章主要經過幾個代碼片斷,分析下局部變量表與操做數棧之間的數據傳遞關係,重點講解iload,istore,iconst_<n>,iadd命令java

提早了解

JVM的幾個概念

  • 局部變量表:每一個棧幀內部都包含一組稱爲局部變量表的變量列表學習

  • 操做數棧:每一個棧幀內部都包含一個操做數棧this

  • iconst_0:把int型的0值壓入操做數棧code

  • iload:將一個局部變量加載到操做數棧上索引

  • istore:將一個數值從操做數棧上存儲到局部變量表中編譯

  • iadd:返回棧頂的兩個元素作加法運算,並加結果壓棧class

如何使用dos查看字節碼文件

首先經過dos進入TestApp.class所在的目錄,而後運行命令javap -c TestApp,便可看到編譯後的字節碼文件test

程序片斷一

  • 如下是一個java源代碼變量

public void test1(){      
    int c=0;              
}
  • 編譯後的字節碼書籍

public void test1();
    Code:
       0: iconst_0
       1: istore_1
       2: return
  • 代碼分析

由於test1()是一個實例方法,因此在局部變量表中,索引爲0的位置會保存該方法所在類的引用(this),因此纔會出現istore_1而不是istore_0

咱們對int c = 0作下拆解,一個常量0,一個變量c。

0: iconst_0   //將常量0壓入操做數棧
1: istore_1   //將棧頂出棧,即c=0
2: return      //由於是void,沒有返回值

程序片斷二

  • Java源代碼以下

public static void test2(){    
    int c=0;                   
}
  • 編譯後的字節碼文件

public static void test2();
    Code:
       0: iconst_0
       1: istore_0
       2: return
  • 分析

由於test2()是一個靜態的方法,不會在局部變量表中插入任何數據。因此你看到的是istore_0而不是像程序片斷一中的istore_1。其餘分析跟程序片斷一相同

程序片斷三

  • java源代碼

public int test3(){         
    int c=0;                
    return c;               
}
  • 編譯後的字節碼

public int test3();
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: ireturn
  • 分析

0: iconst_0        //將常量0壓棧
1: istore_1     //將棧頂出棧,及c=0
2: iload_1      //將變量c壓入棧頂
3: ireturn        //返回棧定元素

程序片斷四

  • Java源代碼

public int test4(int a,int b){       
    int c=0;                         
    return a+b;                      
}
  • 編譯後的字節碼

public int test4(int, int);
    Code:
       0: iconst_0
       1: istore_3
       2: iload_1
       3: iload_2
       4: iadd
       5: ireturn

** 分析

由於test4(int a,int b)是實例方法,因此在局部變量表索引爲0的位置會插入this
由於test4(int a,int b)帶有兩個參數,因此在局部變量索引索引爲1的位置插入a,在索引爲2的位置插入b。

0: iconst_0        //將常量0壓棧
1: istore_3        //將棧頂出棧,即c=0,將c存儲到局部變量表索引爲3的位置
2: iload_1        //將局部變量表中索引爲1的變量壓棧,即a壓棧
3: iload_2        //將局部變量表中索引爲2的變量壓棧,即b壓棧
4: iadd            //將棧頂兩個元素出棧,作加法,而後把結果再入棧(即a,b出棧,將a+b入棧)
5: ireturn        //返回a+b的值

程序片斷五

  • java源代碼

public int test5(int a,int b){    
    int c=0;                      
    c= a+b;                       
    return c;                     
}
  • 編譯後的字節碼

public int test5(int, int);
    Code:
       0: iconst_0
       1: istore_3
       2: iload_1
       3: iload_2
       4: iadd
       5: istore_3
       6: iload_3
       7: ireturn
  • 分析

0: iconst_0        //將常量0壓棧
1: istore_3        //將棧頂出棧,及c=0
2: iload_1        //從局部變量表中加載索引爲1的變量壓棧,即a壓棧
3: iload_2        //從局部變量表中加載索引爲2的變量壓棧,即b壓棧
4: iadd            //將棧頂兩個元素出棧,作加法,而後將結果壓棧,及a+b壓棧
5: istore_3        //將棧頂元素出棧,並保存到局部變量表中,即c=a+b
6: iload_3        //從局部變量表中加載索引爲3的變量壓棧,即c壓棧
7: ireturn        //返回棧頂元素,即返回c
相關文章
相關標籤/搜索