8.使用javap查看字节码文件

1.javap命令概述

如果直接查看Class的二进制文件,我们很难阅读,JDK提供了专门用来分析Class文件的工具javap以窥探Class文件的内部细节。

2. javap命令介绍

C:\Users\admin>javap
用法: javap <options> <classes>
其中, 可能的选项包括:
  -help  --help  -?        输出此用法消息
  -version                 版本信息
  -v  -verbose             输出附加信息
  -l                       输出行号和本地变量表
  -public                  仅显示公共类和成员
  -protected               显示受保护的/公共类和成员
  -package                 显示程序包/受保护的/公共类
                           和成员 (默认)
  -p  -private             显示所有类和成员
  -c                       对代码进行反汇编
  -s                       输出内部类型签名
  -sysinfo                 显示正在处理的类的
                           系统信息 (路径, 大小, 日期, MD5 散列)
  -constants               显示最终常量
  -classpath <path>        指定查找用户类文件的位置
  -cp <path>               指定查找用户类文件的位置
  -bootclasspath <path>    覆盖引导类文件的位置

3. javap解析字节码

3.1. 示例代码

package org.example;

public class Test {
    private int number = 110;

    public int add(){
        number = number + 110;
        return number;
    }
}

3.2. javap解析出Class文件内容的理解

D:\IdeaProjects\MyDemo\target\classes\org\example>javap -v Test.class
Classfile /D:/IdeaProjects/MyDemo/target/classes/org/example/Test.class
  Last modified 2023-6-9; size 390 bytes
  MD5 checksum 6499e1baa710cce861d8f8113327109e
  Compiled from "Test.java"
public class org.example.Test
  minor version: 0        --副版本号 
  major version: 52       --主版本号 jdk1.8
  flags: ACC_PUBLIC, ACC_SUPER    --类访问和属性修饰符
Constant pool:                       --常量池
   #1 = Methodref          #4.#18         // java/lang/Object."<init>":()V    -- 类种方法的符号引用
   #2 = Fieldref           #3.#19         // org/example/Test.number:I       -- 字段的符号引用
   #3 = Class              #20            // org/example/Test  		-- 类或者接口的符号引用
   #4 = Class              #21            // java/lang/Object		-- 类或者接口的符号引用
   #5 = Utf8               number                              -- 字符串常量
   #6 = Utf8               I                                   -- 字符串常量
   #7 = Utf8               <init>						 	-- 字符串常量
   #8 = Utf8               ()V								-- 字符串常量
   #9 = Utf8               Code								-- 字符串常量
  #10 = Utf8               LineNumberTable					 -- 字符串常量
  #11 = Utf8               LocalVariableTable				 -- 字符串常量
  #12 = Utf8               this								-- 字符串常量
  #13 = Utf8               Lorg/example/Test;				 -- 字符串常量
  #14 = Utf8               add								-- 字符串常量
  #15 = Utf8               ()I								-- 字符串常量
  #16 = Utf8               SourceFile						-- 字符串常量
  #17 = Utf8               Test.java						-- 字符串常量
  #18 = NameAndType        #7:#8          // "<init>":()V		-- 字段或方法的符号引用
  #19 = NameAndType        #5:#6          // number:I			-- 字段或方法的符号引用
  #20 = Utf8               org/example/Test					--字符串常量
  #21 = Utf8               java/lang/Object					--字符串常量
{							-- <init> 构造方法
  public org.example.Test();
    descriptor: ()V					-- 构造方法返回值 void
    flags: ACC_PUBLIC				-- 构造方法访问权限 public 
    Code:						   -- Code属性结构,主要是描述代码指令相关
      stack=2, locals=1, args_size=1		-- 参数数量
         0: aload_0							-- 将引用类型局部变量表中下表为0的元素压入操作数栈
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V   -- 调用<init>方法
         4: aload_0							-- 将引用类型局部变量表中下表为0的元素压入操作数栈
         5: bipush        110				 -- 将110压入操作数栈
         7: putfield      #2                  // Field number:I   -- 给堆中的类的实例对象赋值
        10: return							 -- 返回
      LineNumberTable:						 -- 字节码指令行号与源文件行号对应表
        line 3: 0							
        line 4: 4							 
      LocalVariableTable:					 --  局部变量表 this存储在0下标
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lorg/example/Test;

  public int add();							-- add 方法
    descriptor: ()I							-- 方法返回值 int		
    flags: ACC_PUBLIC						-- 方法访问权限public
    Code:									-- Code属性结构,主要是描述代码指令相关
      stack=3, locals=1, args_size=1			-- 最大栈深度3,局部变量表1,参数个数1
         0: aload_0								-- 将引用类型局部变量表中下表为0的元素压入操作数栈
         1: aload_0								-- 将引用类型局部变量表中下表为0的元素压入操作数栈
         2: getfield      #2                  // Field number:I  -- 访问堆中的实例对象值
         5: bipush        110				-- 将110 压入操作数栈	
         7: iadd						   -- 栈顶2个元素相加
         8: putfield      #2                  // Field number:I   -- 给堆中的实例对象值
        11: aload_0							-- 将引用类型局部变量表中下表为0的元素压入操作数栈
        12: getfield      #2                  // Field number:I   -- 访问堆中的实例对象值
        15: ireturn							-- 返回int类型数值
      LineNumberTable:						-- 字节码指令行号与源文件行号对应表
        line 7: 0
        line 8: 11
      LocalVariableTable:					 --  局部变量表 this存储在0下标
        Start  Length  Slot  Name   Signature
            0      16     0  this   Lorg/example/Test;
}
SourceFile: "Test.java"							-- 标识源文件的名称

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值