javajavacjavap

Using javap for reading the byte code


I figured out by reading in the internet that java compiles

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

to

public class Test {
    private String s;

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

Am I right?

Now I tried to comprehend this by myself. So I compile the class Test.java by invoking

javac Test.java

After it, I've read that I can use javap to read the compiled code (=byte code).

So I've tried to see the restructuring from the compiler in the byte code, which I mentioned above (that the decleration is IN the constructor). But how?? Is javap the right tool for that? If yes, with which parameters?

Thanks for your help!

edit:

Ok, thanks so far! Can you explain me please how to read the output of 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
}

Solution

  • Since your field is private, you also need to give the -p argument to see private members. To see what happens with multiple constructors, I added an extra one.

    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
    }
    

    In both constructors, this is basically:

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

    Teaching you bytecode is beyond the scope of StackOverflow. See The Java Virtual Machine Instruction Set for full list of bytecode instructions.