JVM字节码简单示例

本文详细介绍了Java字节码的生成与解析过程,包括javac编译器如何生成字节码文件,以及使用javap工具进行字节码查看。通过示例展示了构造方法的调用、常量池、本地变量表的操作,并分析了字节码指令如aload_0、invokespecial等。此外,还展示了如何查看行号、局部变量表等信息,帮助理解字节码在程序执行中的作用。
摘要由CSDN通过智能技术生成

字节码

编译+简单查看字节码
在这里插入图片描述
字节码

javac -g x.java 添加一个参数g可以在查看字节码文件时看到本地方法表
javap -c -verbose x.class 添加一个参数可以查看常量池 行号 头 在这里插入图片描述

load 间给本地变量表的数据写入到栈中,
store将栈中的数据写入到本地变量表中
这里有两个方法体,第一个中是一个构造方法  
aload_0将本地常量池中零为的操作数压入栈中
调用invokespecial指令,操作数是#1即调用本地常量池中 序号为1 的指令,即调用父类的Object类的初始h化方法
主函数中
        获取静态类    此处对应着获取了一个I/O类的PrintScream类  其后跟两位操作数
        一个String类型
        调用方法  调用PrintScream类的prinln方法
       C:\Users\DELL\Desktop\商城项目\untitled\src>javac -g  HelloWorld.java

任务一

C:\Users\DELL\Desktop\商城项目\untitled\src>javap -c -verbose HelloWorld
Classfile /C:/Users/DELL/Desktop/商城项目/untitled/src/HelloWorld.class
  Last modified 202117; size 689 bytes  
   //时间戳,字节大小
  MD5 checksum 012ea257eb83031171c7bc41bbeb21aa
  Compiled from "HelloWorld.java"
public class HelloWorld
  minor version: 0
  major version: 53   
  //代表jdk8
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #2                          // HelloWorld
  super_class: #8                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1   
  //两个方法,一个main方法,一个
Constant pool:
   #1 = Methodref          #8.#36         // java/lang/Object."<init>":()V
   #2 = Class              #37            // HelloWorld
   #3 = Methodref          #2.#36         // HelloWorld."<init>":()V
   #4 = Long               3l
   #6 = Double             1.55d
   #8 = Class              #38            // java/lang/Object
   #9 = Utf8               <init>
  #10 = Utf8               ()V
  #11 = Utf8               Code
  #12 = Utf8               LineNumberTable
  #13 = Utf8               LocalVariableTable
  #14 = Utf8               this
  #15 = Utf8               LHelloWorld;
  #16 = Utf8               main
  #17 = Utf8               ([Ljava/lang/String;)V
  #18 = Utf8               i
  #19 = Utf8               I
  #20 = Utf8               args
  #21 = Utf8               [Ljava/lang/String;
  #22 = Utf8               helloWorld
  #23 = Utf8               m
  #24 = Utf8               f
  #25 = Utf8               F
  #26 = Utf8               l
  #27 = Utf8               J
  #28 = Utf8               c
  #29 = Utf8               C
  #30 = Utf8               s
  #31 = Utf8               D
  #32 = Utf8               StackMapTable
  #33 = Class              #21            // "[Ljava/lang/String;"
  #34 = Utf8               SourceFile
  #35 = Utf8               HelloWorld.java
  #36 = NameAndType        #9:#10         // "<init>":()V
  #37 = Utf8               HelloWorld
  #38 = Utf8               java/lang/Object
{
  public HelloWorld();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
      //栈深为1,本地变量表中有一个  就是当前这个类
         0: aload_0
         //将常量池中#0压栈
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
        //常量池#1的指令  调用Object类的init方法
         4: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LHelloWorld;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=10, args_size=1
         0: new           #2                  // class HelloWorld
         3: dup
         //复制栈顶指针
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         //将HellWord类存入本地变量表
         8: iconst_1
         //当int取值-1~5时,JVM采用iconst指令将常量压入栈中
         9: istore_2
         //弹出栈顶元素,添加到本地变量表2的位置
        10: fconst_1
        //f 1 入栈
        11: fstore_3
        //保存在3的位置
        12: ldc2_w        #4                  // long 3l
        //此处可看到  long型的3l是存在常量池中的
        15: lstore        4
        //存储到本地变量表序号为4的位置
        17: bipush        99
        19: istore        6
        21: ldc2_w        #6                  // double 1.55d
        24: dstore        7
        //本地常量表中2的元素入栈
        26: iload_2
        //数值5入栈
        27: iconst_5
        //弹出比较栈顶两个值,如果栈顶小则执行,否则跳的34行
        28: if_icmple     34
        31: iinc          2, 1
        //位于slot=2位置的m +1
        34: iconst_0
        //将0压入到栈中
        35: istore        9
        将i弹出栈  存入本地变量表slot=9的位置处
        37: iload         9
        //slot = 9 处的i入栈 
        39: iconst_5
        //常量5压栈
        40: if_icmpge     58
        //弹出两个数比较如果栈顶大的执行
        43: iconst_5
        //将5压栈  此处的5是3+2直接运行后的结果
        44: istore_2
        45: iconst_1
        46: istore_2
        47: bipush        6
        49: istore_2
        50: iconst_1
        51: istore_2
        52: iinc          9, 1
        55: goto          37
        58: return
      LineNumberTable:
        line 3: 0
        line 4: 8
        line 5: 10
        line 6: 12
        line 7: 17
        line 8: 21
        line 9: 26
        line 10: 31
        line 12: 34
        line 13: 43
        line 14: 45
        line 15: 47
        line 16: 50
        line 12: 52
        line 21: 58
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           37      21     9     i   I
            0      59     0  args   [Ljava/lang/String;
            8      51     1 helloWorld   LHelloWorld;
           10      49     2     m   I
           12      47     3     f   F
           17      42     4     l   J
           21      38     6     c   C
           26      33     7     s   D
      StackMapTable: number_of_entries = 3
        frame_type = 255 /* full_frame */
          offset_delta = 34
          locals = [ class "[Ljava/lang/String;", class HelloWorld, int, float, long, int, double ]
          //排序方式参照常量表中的start 
          stack = []
        frame_type = 252 /* append */
          offset_delta = 2
          locals = [ int ]
        frame_type = 250 /* chop */
          offset_delta = 20
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值