美文网首页
java字节码浅学

java字节码浅学

作者: dwwl | 来源:发表于2020-01-06 17:02 被阅读0次

    参考
    字节码指令 : http://gityuan.com/2015/10/24/jvm-bytecode-grammar/

    从字节码角度分析 i++ 和 ++i 实现 : https://www.jianshu.com/p/7988e646a37e

    java代码:

    public class ByteCodeDemo {
        public static void main(String[] args) {
            int i = 1;
            int j = 5;
    
            int dj = ++j;
            int di = i++;
    
            System.out.println(di);
            System.out.println(dj);
        }
    }
    

    class反编译后:

    Compiled from "ByteCodeDemo.java"
    public class com.mpt.pomdemo.test.ByteCodeDemo {
      public com.mpt.pomdemo.test.ByteCodeDemo();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: iconst_1
           1: istore_1
           2: iconst_5
           3: istore_2
           4: iinc          2, 1
           7: iload_2
           8: istore_3
           9: iload_1
          10: iinc          1, 1
          13: istore        4
          15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
          18: iload         4
          20: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
          23: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
          26: iload_3
          27: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
          30: return
    }
    
    
    • load 命令:用于将局部变量表的指定位置的相应类型变量加载到栈顶;
    • store命令:用于将栈顶的相应类型数据保入局部变量表的指定位置;

    iconst_1 int型常量1进栈

    istore_1 栈顶int数值存入变量表中的第2个位置

    iconst_5 int型常量5进栈

    istore_2 栈顶int数值存入变量表中的第3个位置

    iinc 2, 1 将变量表中第3个位置加一

    iload_2 将变量2进栈(下方 i++ 操作没有这一步,所以i++还是没执行加一操作的值)

    istore_3 栈顶int数值存入第4局部变量

    iload_1 将变量1进栈

    iinc 1, 1 将变量表中第二个位置加一

    istore 栈顶int数值存入第1局部变量

    ...

    通过这个简单的例子学习java class文件反编译之后的命令在栈帧中的局部变量表和操作数栈中所作的操作,还有要注意指令的标号,并不是连续的,也就是有些操作并没有展现出来

    java的跨平台特性:
    javac命令:把.java文件编译为class文件
    java命令:jvm把class文件根据当前的操作系统 执行对应的操作
    即编译后的class文件无需修改即可实现跨平台的特性

    为什么JVM不直接把源码解析成机器码去执行?
    1 准备工作:每次执行都需要各种检查
    2 兼容性 : 也可以将别的语言解析成字节码

    相关文章

      网友评论

          本文标题:java字节码浅学

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