实践详解javap命令(反编译字节码)

您所在的位置:网站首页 java生成汇编代码 实践详解javap命令(反编译字节码)

实践详解javap命令(反编译字节码)

2024-07-15 06:19| 来源: 网络整理| 查看: 265

1 缘起

最近在补充JVM相关知识,开始学着看Java字节码反编译结果, 对于目前的我而言,只是单纯地补充知识,没有实际的应用启发, 不过,还是要丰富自己的底层知识, 现整理学习过程的测试文档,分享如下, 帮助读者可以快速掌握反编译Java类,查看相关字节码的汇编信息。

2 javap

JDK8的javap官网文档地址:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javap.html

2.1 简介 javap命令反汇编一个或多个class文件。输出依赖使用的参数,若不使用参数,直接使用javap命令会打印protected和public限定的类属性和方法。javap命令不支持多版本jar。通过类路径形式使用javap命令只能查看当前jar文件的类文件反编译结果,通过URL形式使用javap命令只能查看指定版本类文件的反编译结果。javap命令直接将结果打印到控制台。 2.2 查看javap参数

通过javap -help即可查看javap的参数, Windows10中文平台会直接给出中文描述, 结果如下图所示。

javap -h

由图可知,JDK版本为1.8.0_291,支持invokedynamic,运行时解析调用方法。 在这里插入图片描述

3 Code实战 3.1 原始类

这里先给出完整的原始类:ByteCodeTest.java,为后面生成字节码及反编译做准备, 其中,方法调用给出了5种,分别对应如下反编译标识:

构造器方法(invokespecial)静态方法(invokestatic)接口方法(invokeinterface)虚方法(invokevirtual)动态方法(invokedynamic) 在代码中在对应的位置已给出注释,源码如下: package com.monkey.java_study.clzz; import com.monkey.java_study.common.entity.UserEntity; import com.monkey.java_study.proxy.jdk_proxy.IUserService; import com.monkey.java_study.proxy.jdk_proxy.impl.UserServiceImpl; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * 字节码反编译测试. * * @author xindaqi * @since 2022-08-11 10:48 */ public class ByteCodeTest { public static final String TEST_NAME = "hello world!"; private void test() { System.out.println(">>>>>>>>I am test method in current class"); } public static void main(String[] args) { ByteCodeTest byteCodeTest = new ByteCodeTest(); // invokespecial:调用当前类方法 byteCodeTest.test(); String var1 = "a"; String var2 = "b"; UserEntity userEntity = new UserEntity(); // invokevirtual:调用其他类的方法 userEntity.getNickname(); IUserService userService = new UserServiceImpl(); // invokeinterface userService.add(); List var4 = Stream.of("a", "b", "c").collect(Collectors.toList()); // invokedynamic:运行时解析,调用方法, // invokeinterface:forEach为接口方法 var4.forEach(s -> { if ("a".equals(s)) { // invokestatic:System中out为static方法 System.out.println(">>>>>>>>I am " + s); } }); } } 3.2 编译为字节码

这里使用集成开发环境IDEA,通过build项目将ByteCodeTest.java编译为字节码, 操作方式如下图所示: 在这里插入图片描述

存储在target文件夹下,具体的位置:D:/java-basic-with-maven/target/classes/com/monkey/java_study/clzz/ByteCodeTest.class 编译后项目目录树如下图所示: 在这里插入图片描述

3.3 反编译

这里使用类文件路径方式反编译,即javap [options] class-file-path 其中,class-path-file为类文件路径。

3.3.1 javap -v

查看附加信息。

javap -v ByteCodeTest.class

结果如下图所示,简单的讲解,最前面的信息有:类文件大小、类文件的MD5、JDK版本等, 通过-v看到的信息比较完整,但是比较多,通过-c查看相关反编译指令。 在这里插入图片描述

3.3.2 javap -l

输出行号和本地变量表。

javap -l ByteCodeTest.class

首先,可以看到原始代码的行号与字节码表的标识对应关系,如下图所示, 后面查看字节码序号时可以反查是哪一行的源码。 在这里插入图片描述 本地变量签名结果如下图所示。 在这里插入图片描述

3.3.3 javap -public

显示公共类和成员。

javap -public ByteCodeTest.class

在这里插入图片描述

3.3.4 javap -protected

显示受保护的/公共类和成员

javap -protected ByteCodeTest.class

在这里插入图片描述

3.3.5 javap -package

显示程序包/受保护的/公共类

javap -package ByteCodeTest.class

在这里插入图片描述

3.3.6 javap -p

显示所有类和成员

javap -p ByteCodeTest.class

在这里插入图片描述

3.3.7 javap -c

对代码进行反汇编。

javap -c ByteCodeTest.class

在这里插入图片描述

3.3.8 javap -s

输出内部类型签名。

javap -s ByteCodeTest.class

在这里插入图片描述

3.3.9 javap -sysinfo

显示正在处理类的系统信息(路径、大小、日期、MD5)

javap -sysinfo ByteCodeTest.class

在这里插入图片描述

3.3.10 javap -constants

查看最终常量。

javap -constants ByteCodeTest.class

在这里插入图片描述

4 小结

(1)javap命令反汇编一个或多个class文件。输出依赖使用的参数,若不使用参数,直接使用javap命令会打印protected和public限定的类属性和方法。 (2)javap命令不支持多版本jar。通过类路径形式使用javap命令只能查看当前jar文件的类文件反编译结果,通过URL形式使用javap命令只能查看指定版本类文件的反编译结果。 (3)javap命令直接将结果打印到控制台。 (4)常用查看汇编的命令:javap -c。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3