美文网首页
简单的main方法字节码学习

简单的main方法字节码学习

作者: 上重楼 | 来源:发表于2018-05-11 11:11 被阅读65次

java源码如下:

   public static void main(String[] args) {
       int a = 10;
       int b = 1000;
       System.out.println(add(a, b));
   }

   public static int add(int a, int b) {
       int c = a + b;
       return c;
   }

解析字节码后:

public class Taaa {
 public Taaa();
   Code:
      0: aload_0    //将局部变量表0号位置(this)入栈  实例方法局部变量表的第一个元素一定是对象的引用(this)
      1: invokespecial #1              // Method java/lang/Object."<init>":()V 调用私有的实例化方法
      4: return

 public static void main(java.lang.String[]);
   Code:
      0: bipush        10                  //将操作数10转为int类型入栈,就是源码里的变量a
      2: istore_1                            //将操作数栈 栈顶元素加载到局部变量表索引为1的这个位置
      3: sipush        1000              //将操作数1000转int 入栈,源码里的b
      6: istore_2                           //同 istore_1  只是索引为2
      7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream; 将运行时常量池的#2元素入栈
     10: iload_1                          //读取局部变量表元素1到栈顶
     11: iload_2                           //读取局部变量表元素2到栈顶
     12: invokestatic  #3                  // Method add:(II)I  调用静态方法add
     15: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V 调用输出 
     18: return

 public static int add(int, int);
   Code:
      0: iload_0     //在add这个方法里面,有一个新的局部变量和新的操作数栈,所以源码里的a和b分别作为局部变量表的0和1元素,这行是加载第0个元素到栈顶
      1: iload_1   //这行是加载第1个元素到栈顶
      2: iadd       //将栈的最前面2个元素相加 将结果入栈(栈顶)
      3: istore_2  //将栈顶元素存入局部变量表第2个位置
      4: iload_2   //读取局部变量表第2个位置的元素加载到栈顶
      5: ireturn   //返回栈顶的int类型数据
}

这里有几个小细节,在源码同样都是int类型的 a 和b 在字节码分别用 bipush sipush载入。说明源码里的值被按照其取值范围窄化为小类型了。

局部变量表和操作数栈在每个方法被调用的时候创建,方法的参数顺序就是加入到局部变量表的顺序,比如add方法,a存在局部变量表的0位置,b存在1位置

每一行字节码开头的数值是本行相对于方法起始处的字节偏移量

静态方法局部变量表从0开始,方法的入参依次存入。
实例方法局部变量表从1开始,方法的入参从1开始存。0存了对象的引用

add方法偏移3、4那2行, 先将计算结果从栈顶存入局部变量表,又从局部变量表加载到栈顶,然后才返回栈顶。看上去是在重复计算,是因为源码没有直接 return a+b;
而这个字节码还没经过jvm的优化,只是完完全全的翻译源代码。所以写代码的时候尽量简单点。

相关文章

  • 简单的main方法字节码学习

    java源码如下: 解析字节码后: 这里有几个小细节,在源码同样都是int类型的 a 和b 在字节码分别用 bi...

  • 12.反射

    Java类加载机制: JVM和类:运行Java: java 带有main方法的类名启动JVM,并加载字节码. ...

  • 解释方法之间的调用小实例

    解释执行的main()方法调用解析执行的add()方法的小实例,这个例子如下: 通过Javac编译器编译为字节码文...

  • Java的类加载机制

    一、JVM和类 运行Java:java 带有main方法的类名启动JVM,并加载字节码。 当调用java命令来运行...

  • 深入JVM内核原理-11.JVM字节码执行

    1.概要 javap 简单的字节码执行过程 常用的字节码 使用ASM生成Java字节码 JIT及其相关参数 2.j...

  • 2022五一CRUD知识点合集

    字节码代理 字节码代理方法,会和skywalking 起冲突导致重写方法失败 -- 极海channel 调试页面抖...

  • Jvm基础知识下篇

    一、java执行引擎工作原理:方法调用 1.进行方法调用 Java语言的原子指令是字节码,java方法是对字节码的...

  • 反射获取成员变量 方法 构造方法

    一个类的组成部分1:变量2:方法3:构造方法反射步骤1:字节码文件2:字节码对象 Bean:

  • 获取字段、方法签名

    签名是从class字节码中获取的,所以在获取签名前请先编译工程生成字节码文件。获取字段、方法签名步骤: 进入字节码...

  • 12.JVM学习笔记_字节码知识点整理

    字节码知识点整理 对于Java类中的每个实例方法(非static方法),其在编译后所生成的字节码当中,方法参数的数...

网友评论

      本文标题:简单的main方法字节码学习

      本文链接:https://www.haomeiwen.com/subject/bbxfdftx.html