mrbela
mrbela

Reputation: 4647

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
}

Upvotes: 3

Views: 2657

Answers (2)

BertKing
BertKing

Reputation: 529

The advent of jclasslib Bytecode viewer brings the challenge and opportunity for you.

Upvotes: 0

Andreas
Andreas

Reputation: 159086

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.

Upvotes: 5

Related Questions