2

众所周知,我们可以从源代码中获取抽象语法树,使用类似的工具

org.eclipse.jdt.astview

但是鉴于已编译的类文件,如何获取 AST?有没有现成的工具?烟灰可以吗?

谢谢!

4

3 回答 3

4

但是鉴于已编译的类文件,如何获取 AST?

你不能。从“.class”文件中重建原始源代码的 AST 在技术上是不可能的。很多需要的信息不再以任何形式存在,而其他信息也发生了不可逆转的变化。

有没有现成的工具?

不。

标准的“答案”是使用反编译器,但是:

  • 反编译器无法重建原始 AST(见上文)
  • 反编译器的输出通常与原始源代码相差甚远
  • 通常反编译的代码甚至不会编译。
于 2012-06-19T11:22:23.403 回答
0

反编译并做同样的事情。

字节码没有 S,字节码是AST 到字节码转换的结果。

于 2012-06-19T11:20:01.050 回答
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。

于 2012-06-19T20:29:29.727 回答