在IDEA利用断点debug+解析class文件+jclasslib插件

目录
1、在IDEA利用断点进行debug模式,观察栈帧的入栈出栈
2、在IDEA中使用javap指令对class文件进行解析
3、在IDEA中利用jclasslib插件解析.class文件

在IDEA中输入这样的代码

import java.util.function.DoubleToIntFunction;
/*
(1)现在设置的代码补全是alt+/
(2)快速注释是command+/
(3)快速格式化代码 alt+command+L
(4)利用断点进入debug模式,观察栈的栈帧和局部变量表,进栈出栈操作

进入都out/production/learnJVMdemo文件夹下,有一个当前类的.class文件,对它进行反编译
在Terminal界面下输入反编译指令:javap -v StackFrameTest.class,观察反编译的输出结果
*/
public class TestStackFrame {

    public static void main(String[] args) {

        System.out.println("这是main即将执行");
        TestStackFrame tt = new TestStackFrame();
        try {
            tt.method1();
        }catch (Exception e){
            e.printStackTrace();
        }
        tt.method1();
        System.out.println();
        System.out.println("这是main执行完毕");
    }

    public  void method1(){
        System.out.println("这是method1即将执行");
        int I=10;
        int j=11;
        method2();
        //System.out.println(10/0); //这个会报出一个错误

        System.out.println("这是method1执行完毕");
    }
    public void method2(){
        System.out.println("这是method2即将执行");
        int I=10;
        int j=11;
        method3();
        System.out.println("这是method2执行完毕");
    }
    public void method3(){
        System.out.println("这是method3即将执行");
        int I=10;
        int j=11;
        System.out.println("这是method3执行完毕");
    }
}

1、在IDEA利用断点进行debug模式,观察栈帧的入栈出栈

在代码某处加入红色断点


image.png

右键,进入debug模式


image.png

在下方可以观察debug窗口


image.png

点击箭头朝下的蓝色按钮,执行下一条语句


image.png

2、在IDEA中使用javap指令对class文件进行解析

对上面这段代码进行complie后,会生成.class文件,生成的.class文件在out/production文件夹下,其中learnJVMdemo是你创建的IDEA项目的名称。


image.png

在IDEA的Terminal输入指令


image.png

然后输入反编译指令,对class文件进行反编译


image.png

反编译输入的结果是(仔细分析反编译的结果,能看到学习jvm途中遇见的很多老朋友,例如常量池、局部变量表、<init>方法等):

a1234@MacBook-Pro learnJVMdemo % javap -v TestStackFrame.class
Classfile /Users/a1234/IDEA_project/learnJVMdemo/out/production/learnJVMdemo/TestStackFrame.class
  Last modified 2020年5月21日; size 1446 bytes
  SHA-256 checksum 5c1b47cc1ffe73348dbbc7c2713bff73502254e51e2e528f33c84315f11f2f17
  Compiled from "TestStackFrame.java"
public class TestStackFrame
  minor version: 0
  major version: 58
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #21                         // TestStackFrame
  super_class: #2                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 5, attributes: 1
Constant pool:
   #1 = Methodref          #2.#3          // java/lang/Object."<init>":()V
   #2 = Class              #4             // java/lang/Object
   #3 = NameAndType        #5:#6          // "<init>":()V
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Fieldref           #8.#9          // java/lang/System.out:Ljava/io/PrintStream;
   #8 = Class              #10            // java/lang/System
   #9 = NameAndType        #11:#12        // out:Ljava/io/PrintStream;
  #10 = Utf8               java/lang/System
  #11 = Utf8               out
  #12 = Utf8               Ljava/io/PrintStream;
  #13 = String             #14            // 这是main即将执行
  #14 = Utf8               这是main即将执行
  #15 = Methodref          #16.#17        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #16 = Class              #18            // java/io/PrintStream
  #17 = NameAndType        #19:#20        // println:(Ljava/lang/String;)V
  #18 = Utf8               java/io/PrintStream
  #19 = Utf8               println
  #20 = Utf8               (Ljava/lang/String;)V
  #21 = Class              #22            // TestStackFrame
  #22 = Utf8               TestStackFrame
  #23 = Methodref          #21.#3         // TestStackFrame."<init>":()V
  #24 = Methodref          #21.#25        // TestStackFrame.method1:()V
  #25 = NameAndType        #26:#6         // method1:()V
  #26 = Utf8               method1
  #27 = Class              #28            // java/lang/Exception
  #28 = Utf8               java/lang/Exception
  #29 = Methodref          #27.#30        // java/lang/Exception.printStackTrace:()V
  #30 = NameAndType        #31:#6         // printStackTrace:()V
  #31 = Utf8               printStackTrace
  #32 = Methodref          #16.#33        // java/io/PrintStream.println:()V
  #33 = NameAndType        #19:#6         // println:()V
  #34 = String             #35            // 这是main执行完毕
  #35 = Utf8               这是main执行完毕
  #36 = String             #37            // 这是method1即将执行
  #37 = Utf8               这是method1即将执行
  #38 = Methodref          #21.#39        // TestStackFrame.method2:()V
  #39 = NameAndType        #40:#6         // method2:()V
  #40 = Utf8               method2
  #41 = String             #42            // 这是method1执行完毕
  #42 = Utf8               这是method1执行完毕
  #43 = String             #44            // 这是method2即将执行
  #44 = Utf8               这是method2即将执行
  #45 = Methodref          #21.#46        // TestStackFrame.method3:()V
  #46 = NameAndType        #47:#6         // method3:()V
  #47 = Utf8               method3
  #48 = String             #49            // 这是method2执行完毕
  #49 = Utf8               这是method2执行完毕
  #50 = String             #51            // 这是method3即将执行
  #51 = Utf8               这是method3即将执行
  #52 = String             #53            // 这是method3执行完毕
  #53 = Utf8               这是method3执行完毕
  #54 = Utf8               Code
  #55 = Utf8               LineNumberTable
  #56 = Utf8               LocalVariableTable
  #57 = Utf8               this
  #58 = Utf8               LTestStackFrame;
  #59 = Utf8               main
  #60 = Utf8               ([Ljava/lang/String;)V
  #61 = Utf8               e
  #62 = Utf8               Ljava/lang/Exception;
  #63 = Utf8               args
  #64 = Utf8               [Ljava/lang/String;
  #65 = Utf8               tt
  #66 = Utf8               StackMapTable
  #67 = Class              #64            // "[Ljava/lang/String;"
  #68 = Utf8               i
  #69 = Utf8               I
  #70 = Utf8               j
  #71 = Utf8               SourceFile
  #72 = Utf8               TestStackFrame.java
{
  public TestStackFrame();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 9: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LTestStackFrame;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #13                 // String 这是main即将执行
         5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: new           #21                 // class TestStackFrame
        11: dup
        12: invokespecial #23                 // Method "<init>":()V
        15: astore_1
        16: aload_1
        17: invokevirtual #24                 // Method method1:()V
        20: goto          28
        23: astore_2
        24: aload_2
        25: invokevirtual #29                 // Method java/lang/Exception.printStackTrace:()V
        28: aload_1
        29: invokevirtual #24                 // Method method1:()V
        32: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
        35: invokevirtual #32                 // Method java/io/PrintStream.println:()V
        38: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
        41: ldc           #34                 // String 这是main执行完毕
        43: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        46: return
      Exception table:
         from    to  target type
            16    20    23   Class java/lang/Exception
      LineNumberTable:
        line 13: 0
        line 14: 8
        line 16: 16
        line 19: 20
        line 17: 23
        line 18: 24
        line 20: 28
        line 21: 32
        line 22: 38
        line 23: 46
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           24       4     2     e   Ljava/lang/Exception;
            0      47     0  args   [Ljava/lang/String;
           16      31     1    tt   LTestStackFrame;
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 23
          locals = [ class "[Ljava/lang/String;", class TestStackFrame ]
          stack = [ class java/lang/Exception ]
        frame_type = 4 /* same */

  public void method1();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #36                 // String 这是method1即将执行
         5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: bipush        10
        10: istore_1
        11: bipush        11
        13: istore_2
        14: aload_0
        15: invokevirtual #38                 // Method method2:()V
        18: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
        21: ldc           #41                 // String 这是method1执行完毕
        23: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        26: return
      LineNumberTable:
        line 26: 0
        line 27: 8
        line 28: 11
        line 29: 14
        line 32: 18
        line 33: 26
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      27     0  this   LTestStackFrame;
           11      16     1     I   I
           14      13     2     j   I

  public void method2();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #43                 // String 这是method2即将执行
         5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: bipush        10
        10: istore_1
        11: bipush        11
        13: istore_2
        14: aload_0
        15: invokevirtual #45                 // Method method3:()V
        18: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
        21: ldc           #48                 // String 这是method2执行完毕
        23: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        26: return
      LineNumberTable:
        line 35: 0
        line 36: 8
        line 37: 11
        line 38: 14
        line 39: 18
        line 40: 26
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      27     0  this   LTestStackFrame;
           11      16     1     I   I
           14      13     2     j   I

  public void method3();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #50                 // String 这是method3即将执行
         5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: bipush        10
        10: istore_1
        11: bipush        11
        13: istore_2
        14: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
        17: ldc           #52                 // String 这是method3执行完毕
        19: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        22: return
      LineNumberTable:
        line 42: 0
        line 43: 8
        line 44: 11
        line 45: 14
        line 46: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      23     0  this   LTestStackFrame;
           11      12     1     I   I
           14       9     2     j   I
}
SourceFile: "TestStackFrame.java"
a1234@MacBook-Pro learnJVMdemo % 

3、在IDEA中利用jclasslib插件解析.class文件

首先需要在IDEA中安装jclasslib插件。进入IDEA的设置


image.png

在marketpalce中搜索jclasslib然后进行安装


在marketpalce中搜索jclasslib然后进行安装

安装好之后jclasslib出现在installed界面
安装好之后jclasslib出现在installed界面

重启IDEA,然后打开一个项目代码,在view窗口有一个show bytecode with jclasslib

image.png

点击,出现下面的界面,就可以从中获取到class文件相关的信息了


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容