转载

IDEA插件 -- Class Decompile

最近开始学习IntelliJ插件开发,于是就把之前维护的一款 反编译插件 重新实现了一个版本,并且加入了javap指令的支持,对于理解Java class文件有着不错的帮助。

安装下载

源码: https://github.com/work-helper/class-decompile-intellij

JB插件地址: https://plugins.jetbrains.com/plugin/13914-class-decompile

插件功能

插件的使用很简单,对着Java,Kotlin等JVM上语言文件或者是class文件点击右键,选择 Show Decompile Code ,即可反编译对应的class文件,如下图所示:

IDEA插件 -- Class Decompile

Javap支持

javap 是JDK自带的反编译工具,因此支持需要依赖 External Tools 功能支持,如下图所示在对应菜单中配置javap命令入口,插件则会自动调用对应的javap指令进行反编译。

IDEA插件 -- Class Decompile

反编译能做什么

理解语法糖

反编译能够还原语法糖的实现,帮助你更好的理解编程语言的本质。比如kotlin下的 object class ,反编译后可以很好的理解单例实现。

反编译前

object UserService {
}

cfr反编译后

import kotlin.Metadata;

@Metadata(mv={1, 1, 16}, bv={1, 0, 3}, k=1, d1={"。。。。"})
public final class UserService {
    public static final UserService INSTANCE;

    private UserService() {
    }

    static {
        UserService userService;
        INSTANCE = userService = new UserService();
    }
}

了解Class文件结构

在插件javap指令参数配置上增加 -p -v ,那么反编译能够打印出对应的class文件信息,你可以很清楚的了解的class文件由哪几部分构成。

反编译前

object UserService {
}

javap反编译后(比较长,省略了很多内容)

public final class cn.mrdear.test.UserService
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               cn/mrdear/test/UserService
   #2 = Class              #1             // cn/mrdear/test/UserService
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             // java/lang/Object
   #5 = Utf8               <init>
......
{
  public static final cn.mrdear.test.UserService INSTANCE;
    descriptor: Lcn/mrdear/test/UserService;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL

  private cn.mrdear.test.UserService();
    descriptor: ()V
    flags: ACC_PRIVATE
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 8: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcn/mrdear/test/UserService;

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=2, locals=1, args_size=0
         0: new           #2                  // class cn/mrdear/test/UserService
         3: dup
         4: invokespecial #26                 // Method "<init>":()V              // Field INSTANCE:Lcn/mrdear/test
      LineNumberTable:
        line 8: 0
}
SourceFile: "UserService.kt"
RuntimeVisibleAnnotations:
  0: #13(#14=[I#15,I#15,I#16],#17=[I#15,I#18,I#19],#20=I#15,#21=[s#22],#23=[s#10,s#24,s#6,s#25])

学习Java字节码指令

反编译后能够查看到对应的字节码操作,了解 dup,ldc,invokespecial,astore_0 等相应字节码在JVM上起到的具体作用。

反编译前

object UserService {
}

ASM反编译后

public final class cn/mrdear/test/UserService {

  // compiled from: UserService.kt

  @Lkotlin/Metadata;(mv={1, 1, 16}, bv={1, 0, 3}, k=1, d1={"。。。。 "class-decompile-intellij.main"})

  // access flags 0x19
  public final static Lcn/mrdear/test/UserService; INSTANCE

  // access flags 0x2
  private <init>()V
   L0
    LINENUMBER 8 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcn/mrdear/test/UserService; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x8
  static <clinit>()V
   L0
    LINENUMBER 8 L0
    NEW cn/mrdear/test/UserService
    DUP
    INVOKESPECIAL cn/mrdear/test/UserService.<init> ()V
    ASTORE 0
    ALOAD 0
    PUTSTATIC cn/mrdear/test/UserService.INSTANCE : Lcn/mrdear/test/UserService;
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 1
}

废话不多说,赶快去使用吧。

  • 版权声明: 感谢您的阅读,本文由屈定's Blog版权所有。如若转载,请注明出处。
  • 文章标题: IDEA插件 -- Class Decompile
  • 文章链接: https://mrdear.cn/posts/idea_plugin_decompile.html

V2ray -- 使用Cloudflare CDN加速访问

原文  https://mrdear.cn/posts/idea_plugin_decompile.html
正文到此结束
Loading...