• Java 编译和反编译


    目录

    什么是编程语言?

    什么是编译?

    什么是反编译?

    JDK自带反编译工具javap


    什么是编程语言?

    在介绍编译和反编译之前,我们先来简单介绍下编程语言。编程语言分为低级语言高级语言

    机器语言和汇编语言属于低级语言,直接用计算机指令编写程序。

    而C、C++、Java、Python等属于高级语言,用语句编写程序,语句是计算机指令的抽象表示。

    什么是编译?

    上面提到语言有两种,一种低级语言,一种高级语言。简单的理解:低级语言是计算机认识的语言、高级语言是程序员认识的语言。
    那么如何从高级语言转换成低级语言呢?这个过程其实就是编译。

    将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序的过程就是编译。负责这一过程的处理的工具叫做编译器

    现在我们知道了什么是编译,也知道了什么是编译器。不同的语言都有自己的编译器,Java语言中负责编译的编译器是一个命令:javac

    当我们写完一个 HelloWorld.java 文件后,我们可以使用 javac HelloWorld.java 命令来生成HelloWorld.class文件,这个class类型的文件是JVM可以识别的文件。通常我们认为这个过程叫做Java语言的编译。其实,class文件仍然不是机器能够识别的语言,因为机器只能识别机器语言,还需要JVM再将这种class文件类型字节码转换成机器可以识别的机器语言。

    javac是收录于JDK中的Java语言编译器。该工具可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于Java虚拟机的字节码。

    什么是反编译?

    反编译的过程与编译刚好相反,就是将已编译好的编程语言还原到未编译的状态,也就是找出程序语言的源代码。就是将机器看得懂的语言转换成程序员可以看得懂的语言。Java语言中的反编译一般指将class文件转换成java文件。

    有了反编译工具,我们可以做很多事情,最主要的功能就是有了反编译工具,我们就能读得懂Java编译器生成的字节码。比如我们就可以洞悉Java语法糖背后的原理。

    JDK自带反编译工具javap

    javap并没有将字节码反编译成java文件,而是生成了一种我们可以看得懂字节码。其实javap生成的文件仍然是字节码,只是程序员可以稍微看得懂一些。

    拿一段简单的代码举例

    1. public class switchDemoString {
    2. public static void main(String[] args) {
    3. String str = "world";
    4. switch (str) {
    5. case "hello":
    6. System.out.println("hello");
    7. break;
    8. case "world":
    9. System.out.println("world");
    10. break;
    11. default:
    12. break;
    13. }
    14. }
    15. }

    执行以下两个命令:

    javac Decompilation.java
    javap -c Decompilation.class

    1. public class SwitchDemoString {
    2. public SwitchDemoString();
    3. Code:
    4. 0: aload_0
    5. 1: invokespecial #1 // Method java/lang/Object."":()V
    6. 4: return
    7. public static void main(java.lang.String[]);
    8. Code:
    9. 0: ldc #2 // String world
    10. 2: astore_1
    11. 3: aload_1
    12. 4: astore_2
    13. 5: iconst_m1
    14. 6: istore_3
    15. 7: aload_2
    16. 8: invokevirtual #3 // Method java/lang/String.hashCode:()I
    17. 11: lookupswitch { // 2
    18. 99162322: 36
    19. 113318802: 50
    20. default: 61
    21. }
    22. 36: aload_2
    23. 37: ldc #4 // String hello
    24. 39: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
    25. 42: ifeq 61
    26. 45: iconst_0
    27. 46: istore_3
    28. 47: goto 61
    29. 50: aload_2
    30. 51: ldc #2 // String world
    31. 53: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
    32. 56: ifeq 61
    33. 59: iconst_1
    34. 60: istore_3
    35. 61: iload_3
    36. 62: lookupswitch { // 2
    37. 0: 88
    38. 1: 99
    39. default: 110
    40. }
    41. 88: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
    42. 91: ldc #4 // String hello
    43. 93: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    44. 96: goto 110
    45. 99: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
    46. 102: ldc #2 // String world
    47. 104: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    48. 107: goto 110
    49. 110: return
    50. }

    参考文章: 

    Java| 编译和反编译_YvesHe的博客-CSDN博客_java编译和反编译

  • 相关阅读:
    一文了解优先考虑结果的以「意图」为中心的 Intent-Centric 架构
    【leetcode】【剑指offer Ⅱ】050. 向下的路径节点之和
    前端项目运行报错webpack: Failed to compile.解决
    【图像分类】2022-ConvMixer ICLR
    Everything:文件查找工具,一搜即得
    【b站-湖科大教书匠】1 计算机网络概述-计算机网络微课堂
    C++ Qt数据库模块介绍
    Understanding the Users and Videos by Mining a Novel Danmu Dataset
    Jmeter接口测试和性能测试
    多线程的概念(多线程的代码实现)
  • 原文地址:https://blog.csdn.net/qq_51409098/article/details/126453814