gpt4 book ai didi

java - 为什么不同的Java反编译器显示不同的源代码?

转载 作者:行者123 更新时间:2023-12-02 10:58:55 25 4
gpt4 key购买 nike

我试图通过反编译 .class 文件来了解 Java 编译器的工作原理。我使用了Java反编译器(http://jd.benow.ca/)和showmycode(http://www.showmycode.com/)他们向我展示了 .java 文件中的不同源代码。为什么?我应该相信哪个。

.java 文件

class HelloWorld{
public static void main(String[] args){
System.out.println("Hello, World!");
}
}

java反编译器反编译的.class文件:

import java.io.PrintStream;

class HelloWorld
{
public static void main(String[] paramArrayOfString)
{
System.out.println("Hello, World!");
}
}

由showmycode反编译的.class文件

import java.io.PrintStream;
class HelloWorld {
HelloWorld() {
}
public static void main(string args[])
{
system.out.println("Hello, World!");
}
}

最佳答案

反编译器无法重新创建原始源代码,它只能创建一个新的源代码,该新源代码将编译成与原始源代码相同的二进制文件。

(假设showmycode将解决他们的案例问题,见下文)三个源代码 - 原始代码,由java反编译器创建的代码和由java反编译器创建的代码showmycode幂等。它们以不同的方式编写,但是做完全相同的事情。两个反编译器都是正确的。

以下是差异的解释:

  • 存在/不存在构造函数:每个类都有一个构造函数。如果程序员没有提供构造函数,编译器将生成一个。智能反编译器会识别这一点,并假设它是生成的构造函数,从而从反编译的源代码中忽略它。
  • 数组中[]的位置:声明String[] fooString foo[]是相同的。我建议始终使用 String[] foo,因为在 Java 中(与 C 不同),数组是类型的属性,而不是变量。
  • {} 的格式/位置、缩进等:大多数情况下根本不重要。它对于调试信息(堆栈跟踪的行号)可能有点重要,但这不是代码的重要行为的一部分,而这正是我们感兴趣的。
  • 自动变量(局部变量,包括参数变量)的名称在二进制文件中不可用,因此反编译器在反编译时必须发明新名称。

请注意,showmycode 似乎存在类型名称大小写问题。 Java 区分大小写,必须是 SystemString,而不是 systemstring。似乎 showmycode 遇到了这个错误,这意味着除非您手动修复所有这些类型名称,否则无法再次编译代码。

showmycode 的另一个问题是它如何处理可变参数方法。我将 main 的签名更改为 public static void main(String... args) 来看看我得到了什么,我得到了 public static permanent void main(string args[]) code>,无法编译。如今,反编译器应该生成正确的、可编译的源代码,而 showmycode 却不能。

关于java - 为什么不同的Java反编译器显示不同的源代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27597346/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com