簡體   English   中英

為什么不同的Java反編譯器顯示不同的源代碼?

[英]Why different Java de-compilers show different source code?

我試圖通過反編譯.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!");
    }
}

.class文件由java反編譯器解編譯:

import java.io.PrintStream;

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

.class文件由showmycode解編譯

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

反編譯器無法重新創建原始源代碼,它只能創建一個新的源代碼,它將編譯成與原始源代碼相同的二進制文件。

(假設showmycode將解決他們的案例問題,請參見下文)三個源代碼 - 原始代碼,由java反編譯器創建的代碼和由showmycode創建的代碼冪等的 它們以不同的方式編寫,但完全相同 兩個反編譯器都是對的。

以下是解釋的差異:

  • 構造函數存在/不存在:每個類都有一個構造函數。 如果程序員不提供構造函數,編譯器將生成一個。 智能反編譯器將識別這一點,並假設它是一個的構造函數,它是生成的,因此從反編譯的源代碼中省略它。
  • []對數組的位置:聲明String[] fooString foo[]是相同的。 我建議總是去String[] foo ,因為在Java中(而不是C),作為數組是類型的屬性,而不是變量。
  • {} ,縮進等的格式化/放置:大多數都沒有關系。 它可能對調試信息(堆棧跟蹤的行數)有點重要,但這不是代碼的重要行為的一部分,這是我們感興趣的。
  • 自動變量的名稱(局部變量包括參數變量)在二進制文件中不可用,因此反編譯器必須在反編譯時創建新名稱。

請注意, showmycode似乎與類型名稱的情況有關。 Java區分大小寫,它必須是SystemString ,而不是systemstring 看起來像showmycode這樣會出錯,這意味着除非您手動修復所有這些類型名稱,否則無法再次編譯代碼。

showmycode的另一個問題是它如何處理varargs方法。 我將main的簽名更改為public static void main(String... args)以查看我得到的內容,並且我得到了public static transient void main(string args[]) ,它不能編譯。 現在反編譯器需要生成正確的,可編譯的源代碼,而showmycode則不然。

因為有幾種不同的方式來編寫大多數語句,所有這些都歸結為相同的目標代碼。 通常沒有單一的正確反編譯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM