【问题标题】:Using javap for reading the byte code使用 javap 读取字节码
【发布时间】:2016-07-20 11:17:48
【问题描述】:

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

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

public class Test {
    private String s;

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

我说的对吗?

现在我试图自己理解这一点。所以我通过调用编译类Test.java

javac Test.java

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

所以我试图在字节码中看到编译器的重组,我在上面提到过(decleration 在构造函数中)。但是怎么办?? 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
}

【问题讨论】:

  • 我在您的输出中看到的唯一内容是构造函数。 public Test() 就是它的名字,就像在你的源文件中调用它一样。所以你不需要看太远,它就在你面前。还是我不明白你在找什么?
  • 您预计会有什么变化?这两种形式是等价的。
  • 也许您可以在问题中编辑解释认为您的javap 输出意味着什么,为什么?在我看来,它就像您的第二个代码块,如果我理解您,那就是您期望找到的。所以我不确定你为什么觉得你没有找到它。
  • 感谢您的提示!我稍微改了一下问题!
  • 嗯。问题是,现在您的问题的答案是“是的,这是正确的工具,具有您之前使用的参数,因为它提供了您刚刚从问题中删除的输出”

标签: java javac javap


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    由于您的字段是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

    【讨论】:

      猜你喜欢
      • 2016-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多