解析用GraalVm编译的class文件

发布时间:2024年01月18日

Task1实验材料:

javap的用法

用法: javap <options> <classes>
其中, 可能的选项包括:
  --help -help -h -?               输出此帮助消息
  -version                         版本信息
  -v  -verbose                     输出附加信息
  -l                               输出行号和本地变量表
  -public                          仅显示公共类和成员
  -protected                       显示受保护的/公共类和成员
  -package                         显示程序包/受保护的/公共类
                                   和成员 (默认)
  -p  -private                     显示所有类和成员
  -c                               对代码进行反汇编
  -s                               输出内部类型签名
  -sysinfo                         显示正在处理的类的
                                   系统信息(路径、大小、日期、SHA-256 散列)
  -constants                       显示最终常量
  --module <模块>, -m <模块>       指定包含要反汇编的类的模块
  -J<vm-option>                    指定 VM 选项
  --module-path <路径>             指定查找应用程序模块的位置
  --system <jdk>                   指定查找系统模块的位置
  --class-path <路径>              指定查找用户类文件的位置
  -classpath <路径>                指定查找用户类文件的位置
  -cp <路径>                       指定查找用户类文件的位置
  -bootclasspath <路径>            覆盖引导类文件的位置
  --multi-release <version>        指定要在多发行版 JAR 文件中使用的版本

GNU 样式的选项可使用 = (而非空白) 来分隔选项名称
及其值。

如果只是单纯的用javap +class文件名的话,那只是单纯的反编译class文件而已。

我们都知道class文件的字节码文件,是难以理解的。

用javap详细输出

javap -v  Main.class

很好理解。这里保存了最新更改时间和文件大小为414字节。

类声明:

public class Main

版本信息:

minor version: 0
major version: 61

这表示 Java 编译器的次要版本为 0,主要版本为 61。Java 版本号 61 对应 JDK 17。

访问标志:

flags: (0x0021) ACC_PUBLIC, ACC_SUPER

这表示类具有 ACC_PUBLICACC_SUPER 两个访问标志。

类层次结构:

this_class: #21
super_class: #2

this_class 表示当前类为索引为 21 的常量池项(#21 = Class #22 // Main),而 super_class 表示其父类为索引为 2 的常量池项(#2 = Class #4 // java/lang/Object)。

接口、字段、方法和属性统计:

interfaces: 0, fields: 0, methods: 2, attributes: 1

该类没有实现接口,没有字段,有两个方法,一个属性。

常量池:

Constant pool: ...

常量池包含了类中使用的常量信息,包括方法引用、字段引用、字符串等。

方法信息:

#25 = Utf8 main
#26 = Utf8 ([Ljava/lang/String;)V

这表示类中有一个名为 main 的方法,其描述符为 ([Ljava/lang/String;)V,即主方法。

源文件信息:

#27 = Utf8 SourceFile
#28 = Utf8 Main.java

表示源文件名为 Main.java

  1. 构造函数:

    • aload_0:将当前对象的引用加载到操作数栈上。
    • invokespecial #1:调用父类的构造函数。
    • return:返回。
  2. 主函数:

    • getstatic #7:从静态字段区获取java.lang.System.out对象。
    • ldc #13:将字符串常量"Hello world!"加载到操作数栈上。
    • invokevirtual #15:调用java.io.PrintStream.println方法,将字符串输出到控制台。
    • return:返回。
文章来源:https://blog.csdn.net/m0_63251896/article/details/135670198
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。