Hello!

I have a question regarding the output generated by the javap disassembler.

Lets say we have the following two classes:

 

public class A {
     public int x = 0;
     public int getX() {
          return x;
     }
}

 

and

  

public class Test {
     public static void main(String [] args) {
          A a = new A() {
               public int getX() {
                    return 1;
               }
          };
     int x = a.getX();
     }
}

The output generated after running

javac -g A.java Test.java

and

javap -p -v -s A.class Test$1.class Test.class

is:

 

Classfile /home/stefan/Projects/javap-test/A.class
  Last modified May 7, 2014; size 337 bytes
  MD5 checksum c92d7af447fa7717520d721a44940eb3
  Compiled from "A.java"
public class A
  SourceFile: "A.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#18         //  java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#19         //  A.x:I
   #3 = Class              #20            //  A
   #4 = Class              #21            //  java/lang/Object
   #5 = Utf8               x
   #6 = Utf8               I
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               LA;
  #14 = Utf8               getX
  #15 = Utf8               ()I
  #16 = Utf8               SourceFile
  #17 = Utf8               A.java
  #18 = NameAndType        #7:#8          //  "<init>":()V
  #19 = NameAndType        #5:#6          //  x:I
  #20 = Utf8               A
  #21 = Utf8               java/lang/Object
{
  public int x;
    Signature: I
    flags: ACC_PUBLIC
  public A();
    Signature: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: iconst_0      
         6: putfield      #2                  // Field x:I
         9: return        
      LineNumberTable:
        line 1: 0
        line 2: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      10     0  this   LA;
  public int getX();
    Signature: ()I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: getfield      #2                  // Field x:I
         4: ireturn       
      LineNumberTable:
        line 5: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LA;
}
Classfile /home/stefan/Projects/javap-test/Test$1.class
  Last modified May 7, 2014; size 406 bytes
  MD5 checksum 997ccb68d293f425eed24512bc5fdbf9
  Compiled from "Test.java"
final class Test$1 extends A
  SourceFile: "Test.java"
  EnclosingMethod: #18.#19                // Test.main
  InnerClasses:
       static #2; //class Test$1
  minor version: 0
  major version: 51
  flags: ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#20         //  A."<init>":()V
   #2 = Class              #21            //  Test$1
   #3 = Class              #22            //  A
   #4 = Utf8               <init>
   #5 = Utf8               ()V
   #6 = Utf8               Code
   #7 = Utf8               LineNumberTable
   #8 = Utf8               LocalVariableTable
   #9 = Utf8               this
  #10 = Utf8               
  #11 = Utf8               InnerClasses
  #12 = Utf8               LTest$1;
  #13 = Utf8               getX
  #14 = Utf8               ()I
  #15 = Utf8               SourceFile
  #16 = Utf8               Test.java
  #17 = Utf8               EnclosingMethod
  #18 = Class              #23            //  Test
  #19 = NameAndType        #24:#25        //  main:([Ljava/lang/String;)V
  #20 = NameAndType        #4:#5          //  "<init>":()V
  #21 = Utf8               Test$1
  #22 = Utf8               A
  #23 = Utf8               Test
  #24 = Utf8               main
  #25 = Utf8               ([Ljava/lang/String;)V
{
  Test$1();
    Signature: ()V
    flags: 
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #1                  // Method A."<init>":()V
         4: return        
      LineNumberTable:
        line 4: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LTest$1;
  public int getX();
    Signature: ()I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: iconst_1      
         1: ireturn       
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       2     0  this   LTest$1;
}
Classfile /home/stefan/Projects/javap-test/Test.class
  Last modified May 7, 2014; size 495 bytes
  MD5 checksum 5ef25a1fdb4c9483b7573a8c9a0c993a
  Compiled from "Test.java"
public class Test
  SourceFile: "Test.java"
  InnerClasses:
       static #2; //class Test$1
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #6.#26         //  java/lang/Object."<init>":()V
   #2 = Class              #27            //  Test$1
   #3 = Methodref          #2.#26         //  Test$1."<init>":()V
   #4 = Methodref          #28.#29        //  A.getX:()I
   #5 = Class              #30            //  Test
   #6 = Class              #31            //  java/lang/Object
   #7 = Utf8               
   #8 = Utf8               InnerClasses
   #9 = Utf8               <init>
  #10 = Utf8               ()V
  #11 = Utf8               Code
  #12 = Utf8               LineNumberTable
  #13 = Utf8               LocalVariableTable
  #14 = Utf8               this
  #15 = Utf8               LTest;
  #16 = Utf8               main
  #17 = Utf8               ([Ljava/lang/String;)V
  #18 = Utf8               args
  #19 = Utf8               [Ljava/lang/String;
  #20 = Utf8               a
  #21 = Utf8               LA;
  #22 = Utf8               x
  #23 = Utf8               I
  #24 = Utf8               SourceFile
  #25 = Utf8               Test.java
  #26 = NameAndType        #9:#10         //  "<init>":()V
  #27 = Utf8               Test$1
  #28 = Class              #32            //  A
  #29 = NameAndType        #33:#34        //  getX:()I
  #30 = Utf8               Test
  #31 = Utf8               java/lang/Object
  #32 = Utf8               A
  #33 = Utf8               getX
  #34 = Utf8               ()I
{
  public Test();
    Signature: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return        
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LTest;
  public static void main(java.lang.String[]);
    Signature: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: new           #2                  // class Test$1
         3: dup           
         4: invokespecial #3                  // Method Test$1."<init>":()V
         7: astore_1      
         8: aload_1       
         9: invokevirtual #4                  // Method A.getX:()I
        12: istore_2      
        13: return        
      LineNumberTable:
        line 4: 0
        line 10: 8
        line 11: 13
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      14     0  args   [Ljava/lang/String;
               8       6     1     a   LA;
              13       1     2     x   I
}

 

The a.getX() call from the main method of class Test is translated into bytecode as invokevirtual #4, where #4 is a reference to the getX() method from class A. If I run the example, the getX() method from the anonymous class Test$1 gets invoked as expected. Shouldn't the index of invokevirtual be a reference to the getX() method from class Test$1?

FacebookTwitterLinkedin
Pin It
Joomla Tutorials for Beginners