实践详解javap命令(反编译字节码) |
您所在的位置:网站首页 › java生成汇编代码 › 实践详解javap命令(反编译字节码) |
1 缘起
最近在补充JVM相关知识,开始学着看Java字节码反编译结果, 对于目前的我而言,只是单纯地补充知识,没有实际的应用启发, 不过,还是要丰富自己的底层知识, 现整理学习过程的测试文档,分享如下, 帮助读者可以快速掌握反编译Java类,查看相关字节码的汇编信息。 2 javapJDK8的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,运行时解析调用方法。 这里先给出完整的原始类: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 编译后项目目录树如下图所示: 这里使用类文件路径方式反编译,即javap [options] class-file-path 其中,class-path-file为类文件路径。 3.3.1 javap -v查看附加信息。 javap -v ByteCodeTest.class结果如下图所示,简单的讲解,最前面的信息有:类文件大小、类文件的MD5、JDK版本等, 通过-v看到的信息比较完整,但是比较多,通过-c查看相关反编译指令。 输出行号和本地变量表。 javap -l ByteCodeTest.class首先,可以看到原始代码的行号与字节码表的标识对应关系,如下图所示, 后面查看字节码序号时可以反查是哪一行的源码。 显示公共类和成员。 javap -public ByteCodeTest.class显示受保护的/公共类和成员 javap -protected ByteCodeTest.class显示程序包/受保护的/公共类 javap -package ByteCodeTest.class显示所有类和成员 javap -p ByteCodeTest.class对代码进行反汇编。 javap -c ByteCodeTest.class输出内部类型签名。 javap -s ByteCodeTest.class显示正在处理类的系统信息(路径、大小、日期、MD5) javap -sysinfo ByteCodeTest.class查看最终常量。 javap -constants ByteCodeTest.class(1)javap命令反汇编一个或多个class文件。输出依赖使用的参数,若不使用参数,直接使用javap命令会打印protected和public限定的类属性和方法。 (2)javap命令不支持多版本jar。通过类路径形式使用javap命令只能查看当前jar文件的类文件反编译结果,通过URL形式使用javap命令只能查看指定版本类文件的反编译结果。 (3)javap命令直接将结果打印到控制台。 (4)常用查看汇编的命令:javap -c。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |