2012-06-19 57 views

回答

0

反編譯並做同樣的事情。

字節碼沒有S,字節碼是AST到字節碼轉換的結果

4

但是給定編譯後的類文件,如何獲取ASTs?

你不行。從技術上來說,從「.class」文件重新構建原始源代碼的AST是不可能的。所需的大量信息不再以任何形式出現,其他信息也不可逆轉地發生了變化。

有沒有現有的工具?

標準的「回答」是使用反編譯但:經常

  • 反編譯器不能重構原始AST(見上文)
  • 反編譯的輸出甚至不像原始源代碼
  • 經常反編譯的代碼甚至不會編譯。
+1

我想補充一點,有些工具可以讓你瀏覽一個類文件的結構。任何形式化的規範,包括一個Java類文件,都可以被內化爲某種形式的「AST」,儘管類文件的內部化與源文件的內部化明顯不同。 –

+0

@ NathanD.Ryan你的觀點很有趣。你能否提一下瀏覽類文件結構的工具名稱? – JackWM

+0

@JackWM:ASM(http://asm.ow2.org/)和BCEL(http://commons.apache.org/bcel/)是我們立即想到的。還有其他一些鮮爲人知的,其中一些只是實施了一半。 –

0

怎麼樣在一個給定的類文件,我們使用的工具,像JAD第一反編譯它,那麼我們就可以得到「源代碼」。

即使反編譯的「源代碼」與原始代碼不完全相同,它也共享相同的語義。以下是一個簡單的測試。

原始的Java文件:

package shape.circle; 
public class Circle 
{ int r; // this is radius of a circle 
    public Circle(int r) 
    { this.r = r; 
    } 

    /* get the diameter 
     of this circle 
    */ 
    public int getDiameter() 
    { 
     if(r==0) 
     { System.out.println("r is 0"); 
      return -1; 
     } 
     else 
     { int d = multiply(2,r); 
      return d; 
     } 
    } 

    int multiply(int a, int b) 
    { int c; 
     c = a * b; 
     return c; 
    } 
} 

下面是Circle.class反編譯Java文件。

package shape.circle; 
import java.io.PrintStream; 
public class Circle 
{ 

    public Circle(int i) 
    { r = i; 
    } 

    public int getDiameter() 
    { if(r == 0) 
     { System.out.println("r is 0"); 
      return -1; 
     } else 
     { 
      int i = multiply(2, r); 
      return i; 
     } 
    } 

    int multiply(int i, int j) 
    { 
     int k = i * j; 
     return k; 
    } 

    int r; 
} 

它們幾乎相同。然後和以前一樣,我們可以使用工具源代碼

org.eclipse.jdt.astview 

得到AST。