Kotlin-20-查看Kotlin编译成class后代码的三种方式

目录

1、方法一

1.1、在AndroidStudio中查看

1.2、样码

1.3、输出结果(简单易读)

2、方法二

2.1、kotlin编译成class所在目录

2.2、Kotlin样码

2.3、注意

2.4、Javap -public 输出结果

2.5、javap -p -private 

2.6、Javap -c 输出结果

3、方法三

3.1、Jadx反编译工具


1、方法一

1.1、在AndroidStudio中查看

第一步:选择你要查看你的kotlin文件,然后点击Tools-->Kotlin-->Show Kotlin Bytecode

第二步:点击左上角的 Decompile 按钮就会弹出你想要的class源码

1.2、样码

class TestMain {
    public val msg1 = "类中的变量"
    private val msg2 = "类中的变量"

    companion object {
        val msg3 = "伴生对象的变量"
    }
}

val msg4 = "Kotlin文件中的变量"

fun sayHello(msg: String) {
    println("msg=$msg")
}

fun main() {
    val msg5 = "我要看你的class文件"
    sayHello(msg5)
}

1.3、输出结果(简单易读)

public final class TestMainKt {
   @NotNull
   private static final String msg4 = "Kotlin文件中的变量";

   @NotNull
   public static final String getMsg4() {
      return msg4;
   }

   public static final void sayHello(@NotNull String msg) {
      Intrinsics.checkParameterIsNotNull(msg, "msg");
      String var1 = "msg=" + msg;
      boolean var2 = false;
      System.out.println(var1);
   }

   public static final void main() {
      String msg5 = "我要看你的class文件";
      sayHello(msg5);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }
}

2、方法二

利用命令行 javap [option] *.class 命令

子命令 输出信息
-l    输出行和变量的表
-public只输出公共的方法和成员
-protected只输出public和protected类和成员
-package 只输出包,public和protected类和成员,这是默认情况
-p -private输出所有类和成员
-s 输出内部类型签名
-c 对代码进行反汇编。 eg:类中每一个方法内,包含 java 字节码的指令
-verbose  输出栈大小,方法参数的个数
-costants输出静态 final 常量

 

 

 

 

 

 

 

 

 

 

2.1、kotlin编译成class所在目录

编译后的class文件在app--tmp--kotlin-classes--自己的包名 内

                                                   

2.2、Kotlin样码

class TestMain {
    public val msg1 = "类中的变量"
    private val msg2 = "类中的变量"

    companion object {
        val msg3 = "伴生对象的变量"
    }
}

val msg4 = "Kotlin文件中的变量"

fun sayHello(msg: String) {
    println("msg=$msg")
}

fun main() {
    val msg5 = "我要看你的class文件"
    sayHello(msg5)
}

2.3、注意

在这里需要注意,但我们在一个Kotlin文件中定义了一个类和类外部的一些变量和方法的时候,它在编译后会生成两个class文件。

如下:一个TestMain的类class ,还有一个是TestMainKt.class文件

                                                  

2.4、Javap -public 输出结果

 Javap -public     输出公共的方法和成员 

这里分别输出了上面TestMain.kt文件生成的两个class文件的公共的方法和成员变量

javap -public TestMainKt.class
Compiled from "TestMain.kt"

public final class com.yobo.yobo_kotlin.TestMainKt {
  public static final java.lang.String getMsg2();
  public static final void sayHello(java.lang.String);
  public static final void main();
  public static void main(java.lang.String[]);
}

javap -public TestMain.class
Compiled from "TestMain.kt"
public final class com.yobo.yobo_kotlin.TestMain {
  public static final com.yobo.yobo_kotlin.TestMain$Companion Companion;
  public final java.lang.String getMsg1();
  public com.yobo.yobo_kotlin.TestMain();
  public static final java.lang.String access$getMsg3$cp();
}

2.5、javap -p -private 

javap -p -private  显示所有的类和成员

javap -p -private  TestMainKt.class

public final class com.yobo.yobo_kotlin.TestMainKt {
  private static final java.lang.String msg4;
  public static final java.lang.String getMsg4();
  public static final void sayHello(java.lang.String);
  public static final void main();
  public static void main(java.lang.String[]);
  static {};
}

2.6、Javap -c 输出结果

 Javap -c    对代码进行反汇编。 eg:类中每一个方法内,包含 java 字节码的

可以看到虽然是把我们整个class文件进行了反编译,但是可读性不是很好,这时候我们就推荐第二种方法。

public final class com.yobo.yobo_kotlin.TestMainKt {
  public static final java.lang.String getMsg2();
    Code:
       0: getstatic     #13                 // Field msg2:Ljava/lang/String;
       3: areturn

  public static final void sayHello(java.lang.String);
    Code:
       0: aload_0
       1: ldc           #17                 // String msg
       3: invokestatic  #23                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
       6: new           #25                 // class java/lang/StringBuilder
       9: dup
      10: invokespecial #29                 // Method java/lang/StringBuilder."<init>":()V
      13: ldc           #31                 // String msg=
      15: invokevirtual #35                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      18: aload_0
      19: invokevirtual #35                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      22: invokevirtual #38                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      25: astore_1
      26: iconst_0
      27: istore_2
      28: getstatic     #44                 // Field java/lang/System.out:Ljava/io/PrintStream;
      31: aload_1
      32: invokevirtual #50                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      35: return

  public static final void main();
    Code:
       0: ldc           #56                 // String 我要看你的class文件
       2: astore_0
       3: aload_0
       4: invokestatic  #58                 // Method sayHello:(Ljava/lang/String;)V
       7: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #54                 // Method main:()V
       3: return

  static {};
    Code:
       0: ldc           #8                  // String Kotlin文件中的变量
       2: putstatic     #13                 // Field msg2:Ljava/lang/String;
       5: return
}

3、方法三

3.1、Jadx反编译工具

先给出工具的GitHub地址,可以按照自己喜欢的方式安装并查看功能文档:

https://github.com/skylot/jadx

下载zip包解压后,文件目录如下:

双击jadx-gui就可以打开图形界面:

工具支持apk、dex、jar、aar等格式的文件,可以通用File - Open file选择文件或者直接将文件拖进窗口中,可以算得上一键反编译了,非常简单易用,对比dex2jar & jd-gui组合,完胜。

AndroidStudio写的每个class或者kotlin文件都会编译成单独的dex。图中红色框 0 是java代码, 1 是kotlin代码,我们可以将这些dex直接拖入到jadx反编译工具中查看。

 

下图是随手丢进去的一个apk,可以看到不止代码, 包中的资源也被解出来了。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值