使用javap读取字节码

时间:2016-03-31 20:18:48

标签: java javac javap

我通过在互联网上阅读java编译

来想出来
public class Test {
    private String s = "TESTTEST";
}

public class Test {
    private String s;

    public Test() {
        s = "TESTTEST";
    }
}

我是对的吗?

现在我试着自己理解这一点。所以我通过调用

来编译类Test.java
javac Test.java

之后,我已经读过我可以使用javap来读取已编译的代码(=字节代码)。

所以我试图在字节代码中看到编译器的重组,我在上面提到过(解释是在构造函数中)。但是怎么样? javap是正确的工具吗?如果是,使用哪些参数?

感谢您的帮助!

编辑:

好的,谢谢!您能否解释一下如何阅读javap -c Test的输出?

C:\Users\MyName\Desktop>javap -c Test
Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: ldc           #2                  // String TESTTEST
       7: putfield      #3                  // Field s:Ljava/lang/String;
      10: return
}

2 个答案:

答案 0 :(得分:3)

由于您的字段为private,因此您还需要提供-p参数以查看私有成员。为了了解多个构造函数会发生什么,我添加了一个额外的构造函数。

class Test {
    private String s = "TESTTEST";
    Test() {
    }
    Test(int x) {
    }
}
javap -c -p Test.class
class Test {
  private java.lang.String s;

  Test();
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: ldc           #12                 // String TESTTEST
       7: putfield      #14                 // Field s:Ljava/lang/String;
      10: return

  Test(int);
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: ldc           #12                 // String TESTTEST
       7: putfield      #14                 // Field s:Ljava/lang/String;
      10: return
}

在两个构造函数中,基本上都是这样:

<constructor> {
    super();              // Instructions: 0, 1
    this.s = "TESTTEST";  // Instructions: 4, 5, 7
    return;               // Instructions: 10
}

教你字节码超出了StackOverflow的范围。有关字节码指令的完整列表,请参阅The Java Virtual Machine Instruction Set

答案 1 :(得分:0)

jclasslib Bytecode viewer的出现为您带来了挑战和机遇。