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
相关文章
相关标签/搜索